在使用Pandas处理结构化数据时,分组聚合是核心操作之一,当需要对不同列应用不同的聚合逻辑时,通过字典定义聚合规则是一种非常灵活的方式,能够避免重复编写大量聚合代码,提升开发效率。

字典聚合的基本规则
使用字典定义聚合规则时,字典的键对应DataFrame中需要聚合的列名,值对应该列需要应用的聚合函数。聚合函数可以是Pandas内置的字符串别名,也可以是自定义的函数,还可以是函数组成的列表,实现对单列的多维度聚合。
基础字典结构示例
首先我们创建一个示例DataFrame用于演示:
import pandas as pd
# 创建示例数据
data = {
"category": ["A", "A", "B", "B", "A", "B"],
"value1": [10, 20, 30, 40, 50, 60],
"value2": [1.5, 2.5, 3.5, 4.5, 5.5, 6.5],
"count": [100, 200, 300, 400, 500, 600]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
上述代码创建的DataFrame包含分类列category和三个数值列,接下来我们定义字典实现不同列的聚合。
单列单聚合函数的字典配置
当每个列只需要应用一个聚合函数时,字典的值直接传入对应的函数别名即可,常用的内置别名包括sum、mean、max、min、count等。
# 定义聚合字典:value1求总和,value2求平均值,count求最大值
agg_dict = {
"value1": "sum",
"value2": "mean",
"count": "max"
}
# 按category分组后应用聚合字典
result = df.groupby("category").agg(agg_dict)
print("n单列单聚合结果:")
print(result)
运行后可以看到,A类和B类的value1分别计算了总和,value2计算了平均值,count取了最大值,符合字典定义的规则。
单列多聚合函数的字典配置
如果需要对同一列应用多个聚合函数,可以将字典的值设置为函数组成的列表,此时聚合结果的列名会自动拼接列名和函数名。
# 定义聚合字典:value1同时求总和和平均值,value2求最大值和最小值
agg_dict_multi = {
"value1": ["sum", "mean"],
"value2": ["max", "min"]
}
# 执行聚合操作
result_multi = df.groupby("category").agg(agg_dict_multi)
print("n单列多聚合结果:")
print(result_multi)
此时结果会生成多级列索引,第一级是原始列名,第二级是对应的聚合函数名,方便区分不同聚合结果。
使用自定义函数的字典聚合
除了内置函数,我们还可以在字典中传入自定义函数,自定义函数需要接收一个Series作为输入,返回一个标量作为聚合结果。
# 自定义聚合函数:计算数值的范围(最大值减最小值)
def value_range(s):
return s.max() - s.min()
# 定义包含自定义函数的聚合字典
agg_dict_custom = {
"value1": value_range,
"count": "sum"
}
# 执行聚合
result_custom = df.groupby("category").agg(agg_dict_custom)
print("n自定义函数聚合结果:")
print(result_custom)
上述代码中,value1列应用了自定义的value_range函数计算数值范围,count列应用了内置的sum函数求和。
重命名聚合列的字典配置
默认的多聚合函数结果列名不够直观,我们可以通过将字典的值设置为元组列表的方式,实现聚合函数的同时重命名列名,元组格式为(新列名, 聚合函数)。
# 定义带重命名的聚合字典
agg_dict_rename = {
"value1": [("总_value1", "sum"), ("均_value1", "mean")],
"value2": [("最大_value2", "max"), ("最小_value2", "min")]
}
# 执行聚合
result_rename = df.groupby("category").agg(agg_dict_rename)
print("n重命名后的聚合结果:")
print(result_rename)
这种方式可以让聚合结果的列名更符合业务语义,提升结果的可读性。
注意事项
- 字典的键必须是DataFrame中存在的列名,否则会抛出KeyError异常
- 如果使用自定义函数,函数名不需要加引号,直接传入函数对象即可
- 当聚合结果包含多级列索引时,可以通过result.columns = result.columns.droplevel(0)等方式调整索引层级
- 对于字符串类型的列,也可以使用count、unique等适用的聚合函数