pandas agg函数
agg 的核心优势是灵活性和高效性,尤其适合复杂的分组统计需求。通过组合不同的函数和列,你可以快速生成多维度的统计结果。
·
agg 的核心优势是灵活性和高效性,尤其适合复杂的分组统计需求。通过组合不同的函数和列,你可以快速生成多维度的统计结果。
1. 基本语法
DataFrame.agg(func=None, axis=0, *args, **kwargs)
Series.agg(func=None, axis=0, *args, **kwargs)
func: 要应用的函数(可以是函数名、函数对象、列表或字典)。
axis: 0 或 ‘index’(按列聚合),1 或 ‘columns’(按行聚合)。
2. 常见用法
示例数据准备
import pandas as pd
data = {
'A': [1, 2, 3, 4],
'B': [5, 6, 7, 8],
'C': ['X', 'Y', 'X', 'Y']
}
df = pd.DataFrame(data)
2.1 单列应用单个函数
# 对列'A'求和
df['A'].agg('sum') # 输出: 10
# 等价写法
df['A'].agg(sum)
2.2 单列应用多个函数
# 对列'A'同时求和和求均值
df['A'].agg(['sum', 'mean'])
# 输出:
# sum 10
# mean 2.5
2.3 多列应用不同函数
# 对列'A'求和,列'B'求均值
df.agg({'A': 'sum', 'B': 'mean'})
# 输出:
# A 10.0
# B 6.5
2.4 所有列应用相同函数
# 对所有数值列求和
df.agg('sum')
# 输出:
# A 10
# B 26
2.5 分组后使用 agg
结合 groupby 使用更强大:
# 按列'C'分组,对每组计算'A'的和与'B'的均值
result = df.groupby('C').agg({
'A': 'sum',
'B': ['mean', 'max']
})
# 输出:
# A B
# sum mean max
# C
# X 4 6 7
# Y 6 7 8
2.6 自定义函数
可以传递自定义函数(或 lambda 函数):
# 对列'A'计算最大值与最小值的差
df['A'].agg(lambda x: x.max() - x.min()) # 输出: 3
# 对分组后的数据应用自定义函数
def custom_func(s):
return s.max() * 2
df.groupby('C').agg({
'A': 'sum',
'B': custom_func
})
2.7 重命名聚合结果的列名
使用元组指定新列名:
agg_dict = {
'A': [('total', 'sum'), ('average', 'mean')],
'B': [('max_value', 'max')]
}
df.groupby('C').agg(agg_dict)
3. agg函数运用
示例 1:多级分组 + 多列多函数
场景:按地区和产品类别分组,计算销售额的统计量,并对利润列应用自定义条件聚合。
import pandas as pd
import numpy as np
# 示例数据
data = {
'Region': ['North', 'North', 'South', 'South', 'East', 'East'],
'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
'Sales': [100, 200, 150, 300, 250, 400],
'Profit': [10, 25, -5, 40, 15, 60]
}
df = pd.DataFrame(data)
# 多级分组 + 多函数
result = df.groupby(['Region', 'Category']).agg({
'Sales': ['sum', 'mean', lambda x: x.max() - x.min()], # 匿名函数计算极差
'Profit': [
('positive_profit', lambda x: (x > 0).sum()), # 自定义名称统计正利润次数
('total_profit', 'sum')
]
})
print(result)
输出:
Sales Profit
sum mean <lambda_0> positive_profit total_profit
Region Category
East A 250 250.0 0 1 15
B 400 400.0 0 1 60
North A 100 100.0 0 1 10
B 200 200.0 0 1 25
South A 150 150.0 0 0 -5
B 300 300.0 0 1 40
示例 2:动态聚合 + 参数传递
场景:对数值列动态应用多个分位数计算,并传递参数。
# 定义分位数函数(带参数)
def quantile_range(series, q1=0.25, q2=0.75):
return series.quantile(q2) - series.quantile(q1)
# 对 Sales 和 Profit 同时计算多种分位差
agg_dict = {
'Sales': [('q3-q1', lambda x: quantile_range(x, 0.25, 0.75)),
('q90-q10', lambda x: quantile_range(x, 0.1, 0.9))],
'Profit': 'median'
}
print(df.groupby('Region').agg(agg_dict))
输出:
Sales Profit
q3-q1 q90-q10 median
Region
East 75.0 120.0 37.5
North 50.0 80.0 17.5
South 75.0 120.0 17.5
示例 3:条件聚合 + 混合计算
场景:对成绩表按班级分组,计算通过率(分数≥60为通过),同时统计最高分和平均分。
# 示例数据
scores = {
'Class': ['A', 'A', 'B', 'B', 'B', 'C'],
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva', 'Frank'],
'Math': [85, 45, 90, 55, 70, 80],
'Science': [75, 60, 85, 40, 95, 65]
}
df_scores = pd.DataFrame(scores)
# 自定义通过率函数
def pass_rate(series, threshold=60):
return (series >= threshold).mean()
# 聚合配置
agg_config = {
'Math': [('Avg', 'mean'), ('PassRate', pass_rate), ('Max', 'max')],
'Science': [('Avg', 'mean'), ('PassRate', lambda x: pass_rate(x, 60))]
}
print(df_scores.groupby('Class').agg(agg_config))
输出:
Math Science
Avg PassRate Max Avg PassRate
Class
A 65.000000 0.500000 85 67.500000 1.000000
B 71.666667 0.666667 90 73.333333 0.666667
C 80.000000 1.000000 80 65.000000 1.000000
示例 4:时间序列聚合
场景:按周重采样时间序列数据,计算每周的波动率和总和。
# 生成时间序列数据
date_rng = pd.date_range(start='2023-01-01', end='2023-01-31', freq='D')
data = {
'Date': date_rng,
'Value': np.random.randint(50, 150, size=len(date_rng))
}
df_time = pd.DataFrame(data).set_index('Date')
# 自定义波动率函数(标准差 / 均值)
def volatility(series):
return series.std() / series.mean()
# 按周聚合
weekly_agg = df_time.resample('W').agg({
'Value': [('Total', 'sum'), ('Volatility', volatility)]
})
print(weekly_agg)
输出:
Value
Total Volatility
Date
2023-01-01 124 NaN
2023-01-08 731 0.303868
2023-01-15 737 0.189620
2023-01-22 635 0.288917
2023-01-29 829 0.163650
2023-02-05 150 0.094281
示例 5:链式聚合 + 列重命名
场景:对多列应用不同函数后,重命名。
# 复杂聚合
agg_result = df.groupby('Region').agg(
Sales_Total=('Sales', 'sum'),
Sales_Std=('Sales', 'std'),
Profit_Range=('Profit', lambda x: x.max() - x.min())
).reset_index()
print(agg_result)
输出:
Region Sales_Total Sales_Std Profit_Range
0 East 650 106.066017 45
1 North 300 70.710678 15
2 South 450 106.066017 45
更多推荐



所有评论(0)