【问题标题】:pandas divide two multi index seriespandas 分两个多索引系列
【发布时间】:2023-03-10 02:33:01
【问题描述】:

我有一个看起来像的多索引系列

            value
foo bar baz     
1   A    C    6
         D    2
    B    D    6
         F    4
2   B    C    5
         F    7

我想对 foo 和 bar 求和,以获得每个 foo、bar 的值的总和,而不考虑 baz,我可以使用 df.groupby(level=[0, 1]).sum() 来实现。这个系列看起来像:

        sum_value
foo bar      
1   A      8
    B      10
2   B      12

但是,我想将原来的value 除以新的sum_value,得到baz 的百分比,给定foo 和bar。

            value
foo bar baz     
1   A    C    6/8=.75
         D    2/8=.25
    B    D    6/10=.6
         F    4/10=.5
2   B    C    5/12=.42
         F    7/12=.58

我已尝试df.div(df.groupby(level=[0, 1]).sum()),但收到未实现错误。谢谢!

【问题讨论】:

    标签: python pandas group-by


    【解决方案1】:

    您可以这样做,使用 transform 来获得与 oringal 数据帧的相似索引的总和,然后使用 div 和 Pandas 内在数据对齐:

    df.div(df.groupby(['foo','bar']).transform('sum'))
    

    输出:

                    value
    foo bar baz          
    1   A   C    0.750000
            D    0.250000
        B   D    0.600000
            F    0.400000
    2   B   C    0.416667
            F    0.583333
    

    【讨论】:

    • 只是我的 2 美分。如果 df 已经是多索引数据帧,请使用 df.div(df.groupby(level=[0, 1]).transform('sum'))
    • @LouisYang 如果您的索引级别已命名,那么您可以使用名称或级别,它的工作原理完全相同。
    • 这可能是熊猫的新功能?我使用的版本还不支持。但我也在使用一个相当旧的版本。
    • 不用transformdf.div(df.groupby(['foo','bar']).sum())效率更高。
    • @FinThusiast 你是绝对正确的。这是我关于熊猫的最早答案之一。
    【解决方案2】:
    In [40]: df['value'] = df.reset_index('baz', drop=True).div(df.sum(level=[0,1])).values
    
    In [41]: df
    Out[41]:
                    value
    foo bar baz
    1.0 A   C    0.750000
            D    0.250000
        B   D    0.600000
            F    0.400000
    2.0 B   C    0.416667
            F    0.583333
    

    【讨论】:

      【解决方案3】:

      这里的技巧是使用groupby对象的transform方法:

      from io import StringIO
      import pandas
      
      data = StringIO("""\
      foo bar baz value
      1   A    C    6
      1   A    D    2
      1   B    D    6
      1   B    F    4
      2   B    C    5
      2   B    F    7
      """)
      df = pandas.read_table(data, sep='\s+', index_col=['foo', 'bar', 'baz'])
      result = df.div(df.groupby(level=['foo', 'bar']).transform('sum'))
      print(result)
      
                      value
      foo bar baz          
      1   A   C    0.750000
              D    0.250000
          B   D    0.600000
              F    0.400000
      2   B   C    0.416667
              F    0.583333
      

      Transform 返回与原始数据帧具有相同索引的系列:

      print(df.groupby(level=['foo', 'bar']).transform('sum'))
      
                       value
      foo bar baz       
      1   A   C        8
              D        8
          B   D       10
              F       10
      2   B   C       12
              F       12
      

      【讨论】:

        猜你喜欢
        • 2013-06-30
        • 2021-05-30
        • 2018-10-28
        • 2013-09-08
        • 2021-06-20
        • 1970-01-01
        • 2016-12-27
        相关资源
        最近更新 更多