如何用Pandas将groupby分组均值结果转为宽格式DataFrame?
问题描述
我有如下结构的pandas.DataFrame数据:
import pandas as pd df = pd.DataFrame({ 'Year' : [2001, 2001, 2001, 2001, 2002, 2002, 2002, 2002], 'Month' : ['Aug', 'Aug', 'Sep', 'Sep', 'Aug', 'Aug', 'Sep', 'Sep'], 'Day' : [1, 2, 1, 2, 1, 2, 1, 2], 'Value' : [1, 2, 3, 4, 5, 6, 7, 8] })
我按Month和Year分组并计算均值:
print(df.groupby(['Month', 'Year'])['Value'].mean())
得到的输出结果为:
| Month | Year | |
|---|---|---|
| Aug | 2001 | 1.5 |
| 2002 | 5.5 | |
| Sep | 2001 | 3.5 |
| 2002 | 7.5 |
现在我希望生成如下结构的新DataFrame:
| Year | Aug | Sep |
|---|---|---|
| 2001 | 1.5 | 3.5 |
| 2002 | 5.5 | 7.5 |
请问Pandas模块中是否有可用函数实现该需求?
解决方案
当然有,Pandas提供了多种简洁的方法实现这种数据结构转换,以下是几种常用方案:
方法1:基于分组结果使用unstack()
你已经完成了分组均值计算,直接对分组后的Series调用unstack(),即可将Month层级的索引转为列,再调整格式即可:
grouped = df.groupby(['Month', 'Year'])['Value'].mean() result = grouped.unstack(level='Month').reset_index().rename_axis(None, axis=1) print(result)
unstack(level='Month'):指定将Month索引转为列reset_index():将Year从索引转为普通列rename_axis(None, axis=1):移除列的轴标签,让结果更贴合需求
方法2:用pivot_table()一步完成聚合+转换
如果不想分步操作,可以直接用pivot_table一次性完成分组聚合和结构转换:
result = df.pivot_table( values='Value', index='Year', columns='Month', aggfunc='mean' ).reset_index().rename_axis(None, axis=1) print(result)
这里index指定行维度为Year,columns指定列维度为Month,aggfunc='mean'定义对Value的聚合方式,后续格式调整同方法1。
方法3:聚合后用pivot()转换
若需要先对聚合结果做其他处理,可先将分组结果转为普通DataFrame,再用pivot调整结构:
agg_df = df.groupby(['Year', 'Month'])['Value'].mean().reset_index() result = agg_df.pivot(index='Year', columns='Month', values='Value').reset_index().rename_axis(None, axis=1) print(result)
内容的提问来源于stack exchange,提问作者Niklas
相关产品推荐
相关产品推荐

