我有一个类似的文本文件
item1 value1 0
item1 value2 0
item1 value3 0
item2 value1 0
item1 value2 0
item1 value3 0
我想获得一个 Pandas 数据框,其中每个值作为一列,每个项目作为一行。
例如
item | value1 | value2 | value3 | value4...
item1 | 0 | 0 | 0 | NaN
我知道如何通过迭代数据帧来实现,但我认为可能有一种方法可以通过 groupby 避免迭代(因为这是反模式)?
答案 0 :(得分:2)
您要查找的内容在 Pandas 命名法中称为旋转。这是指向 pandas-pivot 文档的链接。
你只需要这样做:
df.pivot(index="item", columns="value", values="zero_col")
根据您的数据框列名称更改名称。
编辑
我在本地对其进行了测试,至少在一般情况下似乎有效。不过,正如@tdy 建议的那样,在枢轴操作之后可能需要进行一些清理以适应您的用例。
片段:
c = {"items": np.arange(5), "values": np.arange(5), "zero_cols": np.zeros(5)}
df = pd.DataFrame(c, columns=["items", "values", "zero_cols"])
df.pivot(index="items", columns="values", values="zero_cols")
结果如下:
values 0 1 2 3 4
items
0 0.0 NaN NaN NaN NaN
1 NaN 0.0 NaN NaN NaN
2 NaN NaN 0.0 NaN NaN
3 NaN NaN NaN 0.0 NaN
4 NaN NaN NaN NaN 0.0
答案 1 :(得分:1)
@kalgoritmi 的答案似乎对您很有效,但鉴于您的示例数据,它在我这边中断了。我不确定这是否是版本问题(我使用的是 Pandas 1.2.3)。无论如何,这可能对其他人有用。
如果有重复对,立即旋转会抛出重复索引ValueError
:
>>> df = pd.DataFrame({'item': ['item1','item1','item1','item2','item1','item1'], 'value': ['value1','value2','value3']*2, 'number': 0})
item value number
0 item1 value1 0
1 item1 value2 0
2 item1 value3 0
3 item2 value1 0
4 item1 value2 0
5 item1 value3 0
>>> df.pivot(index='item', columns='value', values='number')
ValueError: Index contains duplicate entries, cannot reshape
一种解决方法是在旋转之前聚合重复的对,例如mean()
:
>>> df = df.groupby(['item', 'value'], as_index=False).mean()
item value number
0 item1 value1 0
1 item1 value2 0
2 item1 value3 0
3 item2 value1 0
>>> df.pivot(index='item', columns='value', values='number')
value value1 value2 value3
item
item1 0.0 0.0 0.0
item2 0.0 NaN NaN