如何按多层行对python数据框进行分组?

时间:2018-08-03 12:58:27

标签: python pandas pandas-groupby

我有以下多级数据框:

    //    services.yml
    app.python_service:
    class: AppBundle\Service\PythonService
    arguments:
        $logger: '@monolog.logger.request'
        $url: 'link'
    public: true

     //   in controller
    //use container:
    $pS = $this->container->get('app.python_service');

我想对这些季度进行汇总,所以最终结果如下:

Year   2016                    2017                 
Quarter  3   4                 1                 2      
Month  Sep   Oct   Nov   Dec   Jan  Feb    Mar   Apr   May   Jun
A      0.16  0.95  0.92  0.45  0.30  0.35  0.95  0.88  0.18  0.10
B      0.88  0.67  0.07  0.70  0.74  0.33  0.77  0.21  0.81  0.85
C      0.79  0.56  0.13  0.19  0.94  0.23  0.72  0.62  0.66  0.93

我尝试使用以下公式:

Year     2016        2017   
Quarter  3     4     1     2
A        0.16  2.32  1.60  1.16
B        0.88  1.44  1.85  1.86
C        0.79  0.89  1.89  2.21

但我收到此错误:

df= df.groupby('Quarter').transform('sum')

很显然,这是错误的处理方法。任何人都可以请一个解决方案或寻求解决方案。

其他信息

KeyError: 'Quarter' 命令的输出为:df.index

谢谢!

4 个答案:

答案 0 :(得分:5)

只需使用sum

df.sum(level=[0,1],axis=1)
Out[14]: 
year    2016        2017      
quater     3     4     1     2
A       0.16  2.32  1.60  1.16
B       0.88  1.44  1.84  1.87
C       0.79  0.88  1.89  2.21

答案 1 :(得分:1)

在熊猫中使用groupby时,将根据列数据对数据进行分组。但是,您有成排的组。您所需要做的就是在分组之前和之后对df进行转置。

这是您需要的代码:

首先让我们像您一样创建df:

import pandas as pd

index = pd.MultiIndex.from_tuples([(2016, 3, 'Sep', 'A'),
                                   (2016, 3, 'Sep', 'B'),
                                   (2016, 3, 'Sep', 'C'),
                                   (2016, 4, 'Oct', 'A'),
                                   (2016, 4, 'Oct', 'B'),
                                   (2016, 4, 'Oct', 'C'),
                                   (2016, 4, 'Nov', 'A'),
                                   (2016, 4, 'Nov', 'B'),
                                   (2016, 4, 'Nov', 'C'),
                                   (2017, 1, 'Jan', 'A'),
                                   (2017, 1, 'Jan', 'B'),
                                   (2017, 1, 'Jan', 'C'),
                                   (2017, 1, 'Feb', 'A'),
                                   (2017, 1, 'Feb', 'B'),
                                   (2017, 1, 'Feb', 'C'),
                                   ], names=['Year', 'Quarter', 'Month', 'Group'])

raw_df = pd.Series(range(15), index=index)

df = raw_df.unstack([0,1,2])
print(df)

输出:

Year    2016         2017    
Quarter    3   4        1    
Month    Sep Oct Nov  Jan Feb
Group                        
A          0   3   6    9  12
B          1   4   7   10  13
C          2   5   8   11  14

看起来与您的示例完全相同。现在您只需要一行代码:

new_df = df.transpose().groupby(['Year', 'Quarter']).sum().transpose()
print(new_df)

这是您的输出:

Year    2016     2017
Quarter    3   4    1
Group                
A          0   9   21
B          1  11   23
C          2  13   25

祝你好运!

答案 2 :(得分:0)

df.sum(level=['Year', 'Quater'], axis=1)

编辑:感谢Matt Messersmith关于移调的注意事项

再现完整示例

import pandas as pd

tuples = [(2016, 3, 'Sep'), (2016, 4, 'Oct'), (2016, 4, 'Nov'),
          (2016, 4, 'Dec'), (2017, 1, 'Jan'), (2017, 1, 'Feb'),
          (2017, 1, 'Mar'), (2017, 2, 'Apr'), (2017, 2, 'May'),
          (2017, 2, 'Jun')]

index = pd.MultiIndex.from_tuples(tuples, names=['Year', 'Quater', 'Month'])

df = pd.DataFrame([(0.16, 0.88, 0.79), (0.95, 0.67, 0.56), (0.92, 0.07, 0.13), 
                   (0.45, 0.70, 0.19), (0.30, 0.74, 0.94), (0.35, 0.33, 0.23), 
                   (0.95, 0.77, 0.72), (0.88, 0.21, 0.62), (0.18, 0.81, 0.66), 
                   (0.10, 0.85, 0.93)], 
                  index=index, 
                  columns=["A", "B", "C"])
df = df.T
print(df.sum(level=['Year', 'Quater'], axis=1))

答案 3 :(得分:0)

您可以尝试转置数据,然后sum按所需的索引将其转回所需的方式

df.transpose().sum(level=[0,1]).transpose()

如果您需要调整结果。