首页 > 解决方案 > 将熊猫数据框转换为字典,反之亦然

问题描述

我有一个pandas.DataFrame电话df(这只是一个例子)

col1  col2  col3
  A1    B1    C1
 NaN    B2   NaN
 NaN    B3   NaN
  A2    B4    C2
 Nan    B5    C3
  A3    B6    C4
 NaN   NaN    C5

数据框已排序,每个NaNcol1可以视为包含列中最后一个有效值的单元格。我通过使用获得了这个:

df[["col1"]] = df[["col1"]].fillna(method="ffill")

这使:

col1  col2  col3
  A1    B1    C1
  A1    B2   NaN
  A1    B3   NaN
  A2    B4    C2
  A2    B5    C3
  A3    B6    C4
  A3   NaN    C5

然后,我得到一个dict这样的,它的键是 的值col1。这些键与包含 和 值的 dict 相关col2col3

data = {
    "A1": {"col2": ["B1", "B2", "B3"], "col3": ["C1"]},
    "A2": {"col2": ["B4", "B5"], "col3": ["C2", "C3"]},
    "A3": {"col2": ["B6"], "col3": ["C4", "C5"]}
}

data通过这样做获得:

data = {val: {"col2": group["col2"].dropna().tolist(),
              "col3": group["col3"].dropna().tolist()}
        for val, group in df.groupby("col1")}

这是从 dataframe 转换df为 dict的最终结果data。我无法实现的是如何做相反的事情。如果给定我如何构建最初始df的(也包含NaN值的) ?另外,请随时帮助我改进从to的转换。col1datadfdata

编辑:df包含max(len(data[val]["col2"]), len(data[val]["col3"]))每个valin 的行data。如果NaN需要值来填充行,它们必须位于最后的位置。例如:

data = {
    "A1": {"col1": ["B1"], "col2": ["C1", "C2"]}
}

变成

col1  col2  col3
  A1    B1    C1
  A1   NaN    C2

并不是

col1  col2  col3
  A1   NaN    C1
  A1    B1    C2

标签: pythonpandas

解决方案


我们可以在连接期间使用 a 来单独分解每一列cumcount以对齐。col1然后需要在它被复制的地方被掩盖。

import pandas as pd

df = pd.DataFrame.from_dict(data, orient='index')
df.index.name='col1'

l = []
for col in ['col2', 'col3']:
    s = df.explode(col)
    s['idx'] = s.groupby(level=0).cumcount()
    s = s.set_index('idx', append=True)
    l.append(s[col])

df = pd.concat(l, axis=1)

df = df.reset_index().drop(columns='idx')
df['col1'] = df['col1'].mask(df['col1'].duplicated())

  col1 col2 col3
0   A1   B1   C1
1  NaN   B2  NaN
2  NaN   B3  NaN
3   A2   B4   C2
4  NaN   B5   C3
5   A3   B6   C4
6  NaN  NaN   C5

推荐阅读