python - Python Pandas 按多列分组并追加
问题描述
多亏了Python Pandas Groupby/Append 列,我已经接近实现我想要的目标,但还没有完全实现。
东风:
城市 | 计划 | 问题 1 | 问题 2 | 问题 3 |
---|---|---|---|---|
热那亚 | 服务1 | 啊啊啊 | bbb | ccc |
热那亚 | 服务 2 | ddd | zzz | 年年 |
热那亚 | 服务 3 | ggg | 公私合营 | jjj |
威尼斯 | 服务 2 | lll | vvv | |
威尼斯 | 服务 3 | eee | fff | 嗯 |
预期输出:
城市 | 问题 1 | 问题 2 | 问题 3 | 问题 4 | 问题 5 | 问题 6 | 问题 7 | 问题 8 | 问题 9 |
---|---|---|---|---|---|---|---|---|---|
热那亚 | 啊啊啊 | bbb | ccc | ddd | zzz | 年年 | ggg | 公私合营 | jjj |
威尼斯 | lll | vvv | eee | fff | 嗯 |
基本上我想:
- 按城市分组
- 丢弃计划列(如果可能)
- 附加所有其他参数(它们仍然需要始终按顺序排列,因此如果缺少服务,单元格将为空。
在从链接的解决方案中使用 unstack 和 cumcount 玩了一段时间之后,我仍然缺少一些东西来尊重 Plan 列的顺序,如果缺少服务则用空单元格填充。
这是我正在使用的代码:
import pandas as pd
df = pd.read_csv('input.csv')
df1 = df.set_index('City').stack().reset_index(name='vals')
df1['g'] = 'Param' + df1.groupby('City').cumcount().add(1).astype(str)
df1 = df1.pivot(index='City', columns='g', values='vals')
df1.to_csv('output.csv')
在我的测试中,我从输入中删除了Plan列,但问题是在对输出中的参数进行排序后,例如,如果一个城市只有Service 3,它们仍然在Service 1下对齐。
解决方案
这是一个枢轴问题,但您也可以通过堆叠和取消堆叠来做到这一点:
s = df.set_index(['City', 'Plan']).stack().unstack([1, 2])
s.columns = 'Problem ' + pd.RangeIndex(1, s.shape[1]+1).astype(str)
print (s)
Problem 1 Problem 2 Problem 3 Problem 4 Problem 5 Problem 6 Problem 7 Problem 8 Problem 9
City
Genoa aaa bbb ccc ddd zzz yyy ggg ppp jjj
Venice NaN NaN NaN lll vvv NaN eee fff mmm
另一种使用方式melt
:
s = df.melt(['City', 'Plan']).pivot('City', ['Plan', 'variable'], 'value')
s.columns = 'Problem ' + pd.RangeIndex(1, s.shape[1]+1).astype(str)
print (s)
Problem 1 Problem 2 Problem 3 Problem 4 Problem 5 Problem 6 Problem 7 Problem 8 Problem 9
City
Genoa aaa ddd ggg bbb zzz ppp ccc yyy jjj
Venice NaN lll eee NaN vvv fff NaN NaN mmm
排序有点不同,但服务之间的相对排序被保留了。