如何用Pandas透视表/GroupBy按月份分组列?现有代码结果不符需求
调整Pandas透视表列层级,实现按月份分组的期望输出
我明白你的需求——你希望透视表把月份作为外层列,每个月份下再展示各个Bill列,而不是现在的Bill列在外层、月份在内层的结构。咱们一步步来解决这个问题:
输入数据
先确认下你的输入数据:
| PC | Month | Bill1 | Bill2 | Bill3 |
|---|---|---|---|---|
| A | Feb-19 | 1 | 1 | 1 |
| A | April-19 | 1 | 1 | 1 |
| B | Feb-19 | 1 | 1 | 1 |
| B | April-19 | 1 | 1 | 1 |
| C | Feb-19 | 1 | 1 | 1 |
| C | April-19 | 1 | 1 | 1 |
当前问题
你用这段代码生成透视表:
data_frame4 = pd.pivot_table(data_frame4, index=['PC'], values=['Bill1', 'Bill2', 'Bill3'], columns=['Month'], margins=True, fill_value=0)
得到的输出列层级是Bill1/Bill2/Bill3在外层,月份在内层,和你想要的结构完全相反。
解决方案
关键是交换透视表的列层级顺序,把月份放到外层。你可以在生成透视表后,用swaplevel()交换列的两个层级,再用sort_index()让月份按你想要的顺序排列(如果月份是字符串类型,像你的例子里Feb和Apr可以直接按字符串排序;如果是更复杂的月份格式,建议先转成时间类型再排序)。
修改后的代码如下:
import pandas as pd # 构造你的输入数据(如果已经有现成数据可以跳过这步) data = { 'PC': ['A', 'A', 'B', 'B', 'C', 'C'], 'Month': ['Feb-19', 'April-19', 'Feb-19', 'April-19', 'Feb-19', 'April-19'], 'Bill1': [1]*6, 'Bill2': [1]*6, 'Bill3': [1]*6 } data_frame4 = pd.DataFrame(data) # 生成基础透视表(这里先去掉margins,因为你期望输出里没有总计行;如果需要总计可以之后手动添加) pivot_df = pd.pivot_table( data_frame4, index=['PC'], values=['Bill1', 'Bill2', 'Bill3'], columns=['Month'], fill_value=0 ) # 交换列层级:把Month从内层换到外层,Bill类从外层换到内层 pivot_df = pivot_df.swaplevel(axis=1) # 对列排序,保证月份按Feb-19在前、April-19在后的顺序展示 pivot_df = pivot_df.sort_index(axis=1) print(pivot_df)
最终输出
运行后就能得到你期望的结构:
| PC | Feb-19 | April-19 | ||||
|---|---|---|---|---|---|---|
| Bill1 | Bill2 | Bill3 | Bill1 | Bill2 | Bill3 | |
| A | 1 | 1 | 1 | 1 | 1 | 1 |
| B | 1 | 1 | 1 | 1 | 1 | 1 |
| C | 1 | 1 | 1 | 1 | 1 | 1 |
如果之后需要添加总计行(原代码margins=True的效果),可以在交换层级后用pivot_df.loc['All'] = pivot_df.sum()手动添加,这样不会打乱列层级结构。
内容的提问来源于stack exchange,提问作者Praveen Snowy
相关产品推荐
相关产品推荐

