【问题标题】:Adding total row to pandas DataFrame groupby将总行添加到 pandas DataFrame groupby
【发布时间】:2019-12-13 17:00:55
【问题描述】:

我知道this link,但我没能解决我的问题。

我在pandas.DataFrame.groupby().sum()的DataFrame下面有这个:

                                                          Value
Level      Company         Item
    1            X            a                             100
                              b                             200
                 Y            a                              35
                              b                             150
                              c                              35
    2            X            a                              48
                              b                             100
                              c                              50
                 Y            a                              80

并且想为我必须获得的每个级别的索引添加总行数:

                                                          Value
Level      Company         Item
    1            X            a                             100
                              b                             200
                          Total                             300
                 Y            a                              35
                              b                             150
                              c                              35
                          Total                             520
             Total                                          820
    2            X            a                              48
                              b                             100
                              c                              50
             Total                                          198
                 Y            a                              80
                          Total                              80
               Total                                        278
Total                                                      1098

根据要求

level = list(map(int, list('111112222')))
company = list('XXYYYXXXY')
item = list('ababcabca')
value = [100,200,35,150,35,48,100,50,80]
col = ['Level', 'Company', 'Item', 'Value']
df = pd.DataFrame([level,company,item,value]).T
df.columns = col
df.groupby(['Level', 'Company', 'Item']).sum()

【问题讨论】:

    标签: python python-3.x pandas group-by pivot-table


    【解决方案1】:

    你可以使用:

    m=df.groupby(['Level','Company','Item'])['Value'].sum().unstack()
    m.assign(total=m.sum(1)).stack().to_frame('Value')
    

                         Value
    Level Company Item        
    1     X       a      100.0
                  b      200.0
                  total  300.0
          Y       a       35.0
                  b      150.0
                  c       35.0
                  total  220.0
    2     X       a       48.0
                  b      100.0
                  c       50.0
                  total  198.0
          Y       a       80.0
                  total   80.0
    

    【讨论】:

      【解决方案2】:

      您可以尝试一次堆叠一层:

      m = df.groupby(['Level','Company','Item'])['Value'].sum().unstack(level=['Company','Item'])
      m = m.assign(total=m.sum(1))
      m = m.stack(level='Company')
      m = m.assign(total=m.sum(1))
      m = m.stack(level='Item')
      

      输出有重复的总数:

      Level  Company  Item 
      1      X        a        100.0
                      b        200.0
                      total    300.0
             Y        a         35.0
                      b        150.0
                      c         35.0
                      total    220.0
             total             520.0
                      total    520.0
      2      X        a         48.0
                      b        100.0
                      c         50.0
                      total    198.0
             Y        a         80.0
                      total     80.0
             total             278.0
                      total    278.0
      dtype: float64
      

      【讨论】:

      【解决方案3】:

      试试这个:基本上,这是通过使用两组的总和并连接三个数据帧来创建两个新的 dfs

      level = list(map(int, list('111112222')))
      company = list('XXYYYXXXY')
      item = list('ababcabca')
      value = [100,200,35,150,35,48,100,50,80]
      col = ['Level', 'Company', 'Item', 'Value']
      df = pd.DataFrame([level,company,item,value]).T
      df.columns = col
      
      df1 = (df.groupby(['Level', 'Company', 'Item'])['Value'].sum())
      df2 = (df1.sum(level=0).to_frame().assign(Company='total').set_index('Company', append=True))
      df3 = (df1.groupby(['Level','Company']).sum().to_frame().assign(Item='total').set_index('Item', append=True))
      
      dfx = pd.concat([df1.to_frame().reset_index(),
                       df2.reset_index(),
                       df3.reset_index()],sort=False)
      print(dfx)
      

      输出:

         Level Company   Item  Value
      0      1       X      a    100
      1      1       X      b    200
      2      1       Y      a     35
      3      1       Y      b    150
      4      1       Y      c     35
      5      2       X      a     48
      6      2       X      b    100
      7      2       X      c     50
      8      2       Y      a     80
      0      1   total    NaN    520
      1      2   total    NaN    278
      0      1       X  total    300
      1      1       Y  total    220
      2      2       X  total    198
      3      2       Y  total     80
      

      这并没有像您期望的那样排序。 如果我在不重置索引的情况下连接 3 个 dfs,我将获得预期的排序顺序,但索引是一个多索引列

      dfx = pd.concat([df1.to_frame(), df2, df3]).sort_index()
      

      输出

                     Value
      (1, X, a)        100
      (1, X, b)        200
      (1, X, total)    300
      (1, Y, a)         35
      (1, Y, b)        150
      (1, Y, c)         35
      (1, Y, total)    220
      (1, total)       520
      (2, X, a)         48
      (2, X, b)        100
      (2, X, c)         50
      (2, X, total)    198
      (2, Y, a)         80
      (2, Y, total)     80
      (2, total)       278
      

      我不确定如何将其转换为您的 df 中的列。

      【讨论】:

      • 这是您所期待的吗?
      • 最后一个数据帧有 KeyError: 'Level'
      • 您的数据框中是否有一个名为“级别”的列?你能发布你得到错误的确切声明吗?
      • 我愿意,在最初的那个。错误在第 4 行。 df1 是一个系列,所以你不能分组我猜这是问题所在。
      • 使用您的示例,我可以运行此语句 print(df1.groupby(['Level','Company']).sum().to_frame().assign(Company='total').set_index('Company', append=True)) 而不会出现任何错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多