d = {'X':{'a':['a1'], 'b':['b1']}, 'Y':{'c':['c1','c2'],'d':['d1','d2']}}
df = pd.DataFrame({'variable':['a1','b1','c1','c2','d1','d2'], 'value':[54,67,25,16,34,24]})
我正在尝试将 d 中的值('a1
'、'b1
' 等)替换为 df
中的相应值>(54
、67
等)。理想情况下,我想将它们存储在 pandas 数据框中,并添加 X
和 Y
以及组合值,如下所示:
X [54, 67]
a [54]
b [67]
Y [25,16,34,24]
c [25,16]
d [34,24]
到目前为止,我已经创建了列表推导式来循环字典值,但它看起来有点笨拙。
是否有更直接的方法来实现所需的输出?
最佳答案
简而言之:
repl_values = dict(df.to_dict(orient='split')['data'])
_df = pd.DataFrame(d).unstack().dropna().apply(
lambda x: pd.Series(x).replace(repl_values).tolist())
> _df.groupby(level=0).sum()
X [54, 67]
Y [25, 16, 34, 24]
dtype: object
> _df.groupby(level=1).sum()
a [54]
b [67]
c [25, 16]
d [34, 24]
dtype: object
解释:
要使用 pandas 执行此操作,您可以首先将 df
转换为字典,以使其更易于操作:
repl_values = dict(df.to_dict(orient='split')['data'])
> repl_values
{'a1': 54, 'b1': 67, 'c1': 25, 'c2': 16, 'd1': 34, 'd2': 24}
然后我们可以使用 d
来尝试创建一个数据框,我们可以用 repl_values
中的值替换这些值
> pd.DataFrame(d)
X Y
a [a1] NaN
b [b1] NaN
c NaN [c1, c2]
d NaN [d1, d2]
我们可以尝试对这些值进行分组并删除 NaN
:
grouped = pd.DataFrame(d).unstack().dropna()
> grouped
X a [a1]
b [b1]
Y c [c1, c2]
d [d1, d2]
dtype: object
grouped
中的值可以使用 pandas.DataFrame.replace
进行替换。这里的技巧是,由于每个单元格都包含一个列表,因此我们可以通过预先将其转换为 pd.Series
来对每个单元格应用 replace
:
> grouped.apply(lambda x: pd.Series(x).replace(repl_values))
0 1
X a 54.0 NaN
b 67.0 NaN
Y c 25.0 16.0
d 34.0 24.0
要将值包含在列表中,我们可以使用pd.Series.tolist()
:
_df = grouped.apply(lambda x: pd.Series(x).replace(repl_values).tolist())
> _df
X a [54]
b [67]
Y c [25, 16]
d [34, 24]
dtype: object
在最后一个数据框中,我们拥有所需的所有信息。要获取分组的值,我们只需要做:
_df.groupby(level=0).sum()
X [54, 67]
Y [25, 16, 34, 24]
dtype: object
或者:
_df.groupby(level=1).sum()
a [54]
b [67]
c [25, 16]
d [34, 24]
dtype: object
关于python - 从字典创建 pandas 数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56813228/