【问题标题】:Grouping & aggregating on level 1 index & assigning different aggregation functions using pandas使用 pandas 对 1 级索引进行分组和聚合并分配不同的聚合函数
【发布时间】:2022-01-03 08:49:05
【问题描述】:

我有一个数据框df:

                2019            2020            2021        2022
A       1       10              15              15          31
        2       5               4               7           9
        3       0.3             0.4             0.4         0.7
        4       500             600             70          90
B       1       10              15              15          31
        2       5               4               7           9
        3       0.3             0.4             0.4         0.7
        4       500             600             70          90
C       1       10              15              15          31
        2       5               4               7           9
        3       0.3             0.4             0.4         0.7
        4       500             600             70          90
D       1       10              15              15          31
        2       5               4               7           9
        3       0.3             0.4             0.4         0.7
        4       500             600             70          90

我正在尝试按级别 1 索引 1, 2, 3, 4 进行分组,并为这些 1, 2, 3, 4 索引分配不同的聚合函数,以便 1sum 聚合,2mean 聚合,等等上。所以最终的结果应该是这样的:

            2019            2020            2021        2022
1           40              ...             ...         # sum
2           5               ...             ...         # mean
3           0.3             ...             ...         # mean
4           2000            ...             ...         # sum

我试过了:

df.groupby(level = 1).agg({'1':'sum', '2':'mean', '3':'sum', '4':'mean'})

但我知道1, 2, 3, 4 没有一个列在它们不在的列中,所以我不确定我应该如何处理这个问题。

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    您可以将apply 与自定义函数一起使用,如下所示:

    import numpy as np
    
    aggs = {1: np.sum, 2: np.mean, 3: np.mean, 4: np.sum}
    def f(x):
        func = aggs.get(x.name, np.sum)
        return func(x)
         
    df.groupby(level=1).apply(f)
    

    上面的代码默认使用 sum,所以 14 可以从 aggs 中删除而没有任何不同的结果。这样,只需要指定处理方式与其他组不同的组。

    结果:

          2019    2020   2021    2022               
    1     40.0    60.0   60.0   124.0
    2      5.0     4.0    7.0     9.0
    3      0.3     0.4    0.4     0.7
    4   2000.0  2400.0  280.0   360.0
    

    【讨论】:

    • 有趣的解决方案!我确实想知道你为什么在字典的 get 中使用 np.sum。
    • @BorutFlis:如果所有索引值都在aggs 字典中,则没有必要,但我认为最好有一个默认值。例如,如果大多数组应该使用例如总和那么这些不需要包含在aggs 中(因此在上面的示例中,可以删除 1 和 4,只有指定的会以不同方式处理)。我在答案中添加了一些关于此的更多信息。
    【解决方案2】:

    以防万一您避免了 for 循环。有条件地按索引和聚合切片和分组。

    df1 = (
            df.groupby([df.index.get_level_values(level=1)]).agg(
                lambda x: x.sum() if x.index.get_level_values(level=1).isin([1,4]).any() else x.mean())
            
             
          )
    df1
    
    
    
        2019    2020   2021   2022
    1    40.0    60.0   60.0  124.0
    2     5.0     4.0    7.0    9.0
    3     0.3     0.4    0.4    0.7
    4  2000.0  2400.0  280.0  360.0
    

    【讨论】:

    • 感谢您对其他问题的回复,这种方法有效。有什么原因让我无法在question 上使用我的方式获得预期的结果?
    • 不确定我是否理解你
    猜你喜欢
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多