如何在Pandas DataFrame中按多列分组并生成列表
按日期分组将多列转换为列表的解决方案
先还原你的场景,原始DataFrame可以这样构造:
import pandas as pd data = { 'A': [4,3,3,4,5,2], 'B': [5,5,2,4,4,3], 'C': [5,2,1,3,6,7], 'date': ['2019-06-2', '2019-06-2', '2019-06-2', '2019-06-3', '2019-06-3', '2019-06-3'] } df = pd.DataFrame(data)
你之前用df.groupby('date')[['A','B','C']].apply(list)没得到预期结果,是因为apply(list)会把整个分组的行数据打包成列表,而非对每一列单独生成列表。这里给你两个实用的解决方法:
方法一:使用agg(list)(推荐,简洁高效)
这是最直接的实现方式,agg()(aggregate的缩写)可以对指定的每一列单独应用聚合函数,用list作为聚合函数,刚好能把每组的列值转换成对应列表:
result = df.groupby('date')[['A', 'B', 'C']].agg(list).reset_index()
执行后就能得到你想要的结果:
| date | A | B | C | |
|---|---|---|---|---|
| 0 | 2019-06-2 | [4, 3, 3] | [5, 5, 2] | [5, 2, 1] |
| 1 | 2019-06-3 | [4, 5, 2] | [4, 4, 3] | [3, 6, 7] |
reset_index()的作用是把date从分组索引变回普通列,让结构完全匹配你的期望。
方法二:使用apply结合自定义lambda(灵活扩展)
如果之后你需要对列做额外处理(比如去重、排序),可以用这种更灵活的方式:
result = df.groupby('date').apply(lambda x: pd.Series({ 'A': x['A'].tolist(), 'B': x['B'].tolist(), 'C': x['C'].tolist() })).reset_index()
这里的lambda函数接收每个分组的子DataFramex,对每一列调用tolist()生成列表,再用pd.Series把这些列表映射成对应列,最后用reset_index()调整结构即可。
两种方法都能满足需求,优先推荐第一种,它的执行效率更高,代码也更简洁。
内容的提问来源于stack exchange,提问作者astroluv
相关产品推荐
相关产品推荐

