Pandas: 将值从一列移动到合适的列
我在网上查找信息时遇到了一些困难。我有一个简单的数据表,长得像这样:
样本 | 主题 | 人 | 地点 | 物品 |
---|---|---|---|---|
1-1 | 珍妮特 | |||
1-1 | 波士顿 | |||
1-1 | 帽子 | |||
1-2 | 克里斯 | |||
1-2 | 奥斯丁 | |||
1-2 | 围巾 |
我想把主题这一列的值移动到它们应该在的位置,这样我最终得到的结果应该像这样:
样本 | 主题 | 人 | 地点 | 物品 |
---|---|---|---|---|
1-1 | 珍妮特 | 珍妮特 | 波士顿 | 帽子 |
1-2 | 克里斯 | 克里斯 | 奥斯丁 | 围巾 |
我看过一些数据处理的方法,比如透视表和转置,但这些似乎不太合适。
如果有任何建议,我会非常感激! :)
2 个回答
2
试试这个:
out = (
df.groupby("Sample")["Subject"]
.apply(lambda x: pd.Series([*x], index=["Person", "Place", "Thing"]))
.unstack(level=1)
).reset_index()
# If `Subject` column is required, then:
# out["Subject"] = out["Person"]
print(out)
输出结果是:
Sample Person Place Thing
0 1-1 Janet Boston Hat
1 1-2 Chris Austin Scarf
1
如果这些组是排好序的,并且模式总是一样的(没有缺失值),那么可以用numpy来重新整理数据:
cols = ['Person', 'Place', 'Thing']
out = df.loc[::len(cols), ['Sample']].reset_index(drop=True)
out[cols] = df['Subject'].to_numpy().reshape(-1, len(cols))
如果想要更通用的方法,只要假设每组中的类别顺序总是相同,可以用groupby.cumcount
来找出每组的位置,然后用map
来映射名称,最后再用pivot
:
order = ['Person', 'Place', 'Thing']
out = (df.assign(col=df.groupby('Sample').cumcount()
.map(dict(enumerate(order))))
.pivot(index='Sample', columns='col', values='Subject')
.reset_index().rename_axis(columns=None)
)
还有一种用rename
的方法:
order = ['Person', 'Place', 'Thing']
out = (df.assign(col=df.groupby('Sample').cumcount())
.pivot(index='Sample', columns='col', values='Subject')
.rename(columns=dict(enumerate(order)))
.reset_index().rename_axis(columns=None)
)
输出结果:
Sample Person Place Thing
0 1-1 Janet Boston Hat
1 1-2 Chris Austin Scarf
最后,如果你真的想要“Subject”这一列,可以用insert
把它加进去:
out.insert(1, 'Subject', out['Person'])
print(out)
Sample Subject Person Place Thing
0 1-1 Janet Janet Boston Hat
1 1-2 Chris Chris Austin Scarf
时间比较
如果你能使用numpy的方法,它对输入的要求更严格,但速度会快很多: