在 1 级索引上分组和聚合并使用 pandas 分配不同的聚合函数

Grouping & aggregating on level 1 index & assigning different aggregation functions using pandas

我有一个数据框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 聚合, 2 通过 mean,依此类推。因此最终结果将如下所示:

            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 中的 none 在它们不在的列中,所以我不确定我应该如何处理这个问题。

您可以将 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

以防万一你在避免 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