我有一个如下所示的 df,我想将值转换为列(枢轴)操作。我无法执行,因为我的数据在列表中。
我的示例输入有两列(分数和类别)。这些列是有序值。即,第 19 类的分数为 0.97,而第 0 类的分数为 0.77。我想转换我的 df,使类值成为列名,并且相应的分数将在相应的列中。
样本输入:
file_name scores classes
0 voc_32.jpg [0.97, 0.77] [19.0, 0.0]
1 voc_22.jpg [0.92, 0.64, 0.83, 0.55] [17.0, 1.0, 11.0, 11.0]
预期输出:
file_name 0 1 11 17 19
0 voc_32.jpg 0.77 0.97
1 voc_22.jpg 0.64 [0.83, 0.55] 0.92
任何帮助都是可观的。
答案 0 :(得分:3)
在列表推导中创建字典列表并传递给DataFrame
构造函数,最后通过DataFrame.join
添加到原始字典:
df1 = (pd.DataFrame([dict(zip(b, a)) for a, b in zip(df.scores, df.classes)],
index=df.index).sort_index(axis=1).rename(columns=int))
df2 = df[['file_name']].join(df1)
使用 DataFrame.pop
删除列的类似解决方案:
df1 = (pd.DataFrame([dict(zip(b, a)) for a, b in zip(df.pop('scores'), df.pop('classes'))],
index=df.index).sort_index(axis=1).rename(columns=int))
df2 = df.join(df1)
print (df2)
file_name 0 1 11 17 19
0 voc_32.jpg 0.77 NaN NaN NaN 0.97
1 voc_22.jpg NaN 0.64 0.83 0.92 NaN
编辑:对于列表,如果多个类使用 Series.explode
作为 flattem,然后在 GroupBy.agg
中聚合自定义函数并通过 Series.unstack
进行重塑:
f = lambda x: list(x) if len(x) > 1 else x
df1 = (df.apply(pd.Series.explode)
.groupby(['file_name','classes'])['scores']
.agg(f)
.unstack()
.rename(columns=int))
print (df1)
classes 0 1 11 17 19
file_name
voc_22.jpg NaN 0.64 [0.83, 0.85] 0.92 NaN
voc_32.jpg 0.77 NaN NaN NaN 0.97
df2 = df[['file_name']].join(df1, on='file_name')
print (df2)
file_name 0 1 11 17 19
0 voc_32.jpg 0.77 NaN NaN NaN 0.97
1 voc_22.jpg NaN 0.64 [0.83, 0.85] 0.92 NaN