在 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
索引分配不同的聚合函数,以便 1
由 sum
聚合, 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,因此 1
和 4
可以从 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
我有一个数据框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
索引分配不同的聚合函数,以便 1
由 sum
聚合, 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,因此 1
和 4
可以从 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