现在位置: 首页 > Pandas 教程 > 正文

Pandas groupby.agg() 函数

Pandas 常用函数 Pandas 常用函数


groupby.agg() 是 Pandas 中功能最强大的聚合函数之一,它允许你对分组后的数据同时应用多个不同的聚合函数。

sum()mean() 等单一聚合函数不同,agg() 可以一次性计算多个统计指标,比如同时计算每个分组的总和、平均值、最大值、最小值等。

在数据分析中,经常需要对数据同时进行多种统计分析,agg() 函数可以让这一过程变得简洁高效。


基本语法与参数

agg() 是 GroupBy 对象的成员函数,需要先使用 groupby() 分组后再调用。

语法格式

GroupBy.agg(func=None, axis=0, *args, engine=None, engine_kwargs=None, **kwargs)

参数说明

参数 类型 说明 默认值
func str、list、dict 或 callable 聚合函数。可以是单个函数名、函数列表、对各列指定不同函数的字典。 None
axis int 应用聚合的轴方向,0 表示按行(分组维度),1 表示按列。 0
args tuple 传递给聚合函数的额外位置参数。 ()
engine str 指定计算引擎,可以是 'cython' 或 'numba'。None 表示由 Pandas 自动选择。 None
engine_kwargs dict 传递给底层引擎的额外参数字典。 None

返回值

  • 返回类型SeriesDataFrame
  • 说明:返回分组聚合后的结果,结果结构取决于 func 参数和分组方式。

实例

让我们通过一系列从简单到复杂的例子,彻底掌握 groupby.agg() 的用法。

示例 1:使用内置聚合函数

最简单的方式是直接使用 Pandas 内置的聚合函数名称,如 'sum'、'mean'、'max'、'min'、'count' 等。

实例

import pandas as pd

# 创建销售数据 DataFrame
data = {
    '地区': ['华北', '华东', '华南', '华北', '华东', '华南', '华北', '华东'],
    '产品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B'],
    '销售额': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100],
    '数量': [10, 20, 15, 18, 22, 16, 12, 21]
}
df = pd.DataFrame(data)

print("原始销售数据:")
print(df)
print()

# 按"地区"分组,对"销售额"列同时应用多个聚合函数
# 使用字符串列表指定多个聚合函数
result = df.groupby('地区')['销售额'].agg(['sum', 'mean', 'max', 'min', 'count'])

print("每个地区销售额的汇总统计:")
print(result)
print()

# 同时对"销售额"和"数量"列进行聚合
result_all = df.groupby('地区').agg({
    '销售额': ['sum', 'mean'],
    '数量': ['sum', 'mean']
})

print("各地区销售和数量的综合统计:")
print(result_all)

运行结果:

原始销售数据:
  地区  产品   销售额   数量
0  华北   A   1000    10
1  华东   B   2000    20
2  华南   C   1500    15
3  华北   B   1800    18
4  华东   A   2200    22
5  华南   C   1600    16
6  华北   A   1200    12
7  华东   B   2100    21

每个地区销售额的汇总统计:
        sum    mean   max   min  count
地区
华东  7100  1775.0  2200  2000      4
华南  3100  1550.0  1600  1500      2
华北  4000  1333.333333  1800  1000      3

各地区销售和数量的综合统计:
              销售额         数量
              sum    mean  sum   mean
地区
华东  7100  1775.0   83  20.75
华南  3100  1550.0   31  15.50
华北  4000  1333.333333   40  13.33

代码解析:

  1. ['sum', 'mean', 'max', 'min', 'count'] 使用列表可以同时指定多个聚合函数。
  2. 返回的结果是一个 DataFrame,列名由函数名和原始列名组成(多层列索引)。
  3. 使用字典可以为不同的列指定不同的聚合函数。

示例 2:使用自定义聚合函数

除了内置函数,agg() 还支持自定义函数,这大大扩展了其灵活性。

实例

import pandas as pd
import numpy as np

# 创建学生成绩数据
data = {
    '班级': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'A'],
    '姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '郑十'],
    '语文': [85, 92, 78, 88, 95, 82, 90, 87],
    '数学': [90, 85, 92, 78, 88, 91, 85, 89]
}
df = pd.DataFrame(data)

print("学生成绩数据:")
print(df)
print()

# 定义自定义聚合函数
def range_func(x):
    """计算最大值与最小值的差(极差)"""
    return x.max() - x.min()

def coefficient_of_variation(x):
    """计算变异系数(标准差/平均值)"""
    return x.std() / x.mean() * 100

# 使用自定义函数进行聚合
# 可以使用函数名(字符串)或直接传入函数对象
result = df.groupby('班级').agg({
    '语文': ['sum', 'mean', range_func],  # 对语文:总和、平均值、极差
    '数学': ['sum', 'mean', coefficient_of_variation]  # 对数学:总和、平均值、变异系数
})

print("各班级的自定义统计:")
print(result)
print()

# 也可以直接在列表中使用自定义函数
result2 = df.groupby('班级')['数学'].agg(['mean', range_func, 'std'])
print("各班级数学成绩的统计(包含自定义极差和标准差):")
print(result2)

运行结果:

学生成绩数据:
   班级  姓名  语文  数学
0  A   张三   85   90
1  A   李四   92   85
2  A   王五   78   92
3  B   赵六   88   78
4  B   孙七   95   88
5  B   周八   82   91
6  B   吴九   90   85
7  A   郑十   87   89

各班级的自定义统计:
               语文                 数学
              sum   mean range_func  sum    mean coefficient_of_variation
班级
A    342  85.5  14.0  425   88.25  5.019099

B    355  88.75  12.0  342   85.5  7.030

各班级数学成绩的统计(包含自定义极差和统计):
班级
A    88.25  5.0  2.692582
B    85.50  13.0  6.0

代码解析:

  • 自定义函数接收一个 Series 作为参数,返回一个标量值。
  • 函数名可以以字符串形式传入(如 'sum'),也可以直接传入函数对象。
  • 使用自定义函数可以实现任意复杂的聚合逻辑。

示例 3:使用字符串别名和 lambda 函数

agg() 支持多种函数指定方式,包括 lambda 表达式和内置字符串别名。

实例

import pandas as pd

# 创建员工工资数据
data = {
    '部门': ['销售', '销售', '技术', '技术', '行政', '行政', '销售', '技术'],
    '岗位': ['专员', '经理', '专员', '经理', '专员', '经理', '专员', '经理'],
    '工资': [5000, 8000, 7000, 12000, 4500, 9000, 5500, 11000],
    '工龄': [2, 5, 3, 8, 1, 6, 2, 7]
}
df = pd.DataFrame(data)

print("员工工资数据:")
print(df)
print()

# 使用 lambda 函数进行灵活的自定义计算
# 计算每个部门工资的中位数与平均值的差异
result = df.groupby('部门').agg({
    '工资': [
        ('平均工资', 'mean'),  # 给聚合结果起别名
        ('最高工资', 'max'),
        ('最低工资', 'min'),
        ('工资极差', lambda x: x.max() - x.min())
    ],
    '工龄': [
        ('平均工龄', 'mean'),
        ('最高工龄', 'max'),
        ('最低工龄', 'min')
    ]
})

print("各部门工资和工龄的综合统计:")
print(result)
print()

# 使用 agg 的简写形式
result2 = df.groupby('部门')['工资'].agg(
    平均='mean',
    总和='sum',
    人数='count'
)

print("使用命名参数形式的聚合结果:")
print(result2)

运行结果:

员工工资数据:
  部门   岗位    工资   工龄
0  销售   专员  5000    2
1  销售   经理  8000    5
2  技术   专员  7000    3
3  技术   经理  12000   8
4  行政   专员  4500    1
5  行政   经理  9000    6
6  销售   专员  5500    2
7  技术   经理  11000   7

各部门工资和工龄的综合统计:
                   工资                    工龄
            平均工资  最高工资  最低工资  工资极差  平均工龄  最高工龄  最低工龄
部门
技术   10000.0  12000   7000   5000   6.0    8    3
行政   6750.0   9000    4500   4500   3.5    6    1
销售   6166.666667  8000    5000   3000   3.0    5    1

使用命名参数形式的聚合结果:
          平均     总和   人数
部门
技术    10000.0  30000   3
行政     6750.0  13500   2
销售   6166.666667  18500   3

代码解析:

  • 使用元组 ('别名', '函数名') 可以给聚合结果列指定自定义名称。
  • Lambda 表达式可以直接在 agg() 中使用,实现简单的自定义逻辑。
  • 命名参数形式(关键字参数)可以更直观地为结果列指定名称。

示例 4:按多列分组并使用 agg

agg() 也可以与多列分组配合使用,处理更复杂的数据分析需求。

实例

import pandas as pd

# 创建销售数据
data = {
    '地区': ['华北', '华东', '华南', '华北', '华东', '华南', '华北', '华东', '华南'],
    '产品': ['A', 'B', 'C', 'B', 'A', 'C', 'A', 'B', 'C'],
    '销售额': [1000, 2000, 1500, 1800, 2200, 1600, 1200, 2100, 1700],
    '利润': [200, 400, 300, 360, 440, 320, 240, 420, 340]
}
df = pd.DataFrame(data)

print("销售数据:")
print(df)
print()

# 按地区和产品分组,对销售额和利润进行多种聚合
result = df.groupby(['地区', '产品']).agg({
    '销售额': ['sum', 'mean', 'count'],
    '利润': ['sum', 'mean']
})

print("按地区和产品分组后的聚合结果:")
print(result)
print()

# 使用 reset_index 转换为普通 DataFrame 格式
result_flat = df.groupby(['地区', '产品'], as_index=False).agg({
    '销售额': ['sum', 'mean'],
    '利润': ['sum', 'mean']
})

# 展平多层列索引
result_flat.columns = ['_'.join(col).strip('_') for col in result_flat.columns.values]

print("展平后的结果:")
print(result_flat)

运行结果:

销售数据:
 地区  产品   销售额   利润
0  华北   A   1000  200
1  华东   B   2000  400
2  华南   C   1500  300
3  华北   B   1800  360
4  华东   A   2200  440
5  华南   C   1600  320
6  华北   A   1200  240
7  华东   B   2100  420
9  华南   C    1700  340

按地区和产品分组后的聚合结果:
              销售额            利润
               sum  mean count   sum  mean
地区 产品
华东 A   2200  2200.0     1  440  440.0
     B   4100  2050.0     2  4100  4100.0
华南 C   3100  1550.0     2  3100  1550.0
华北 A   2200  1100.0     2  440  220.0
     B   1800  1800.0     1  360  360.0

展平后的结果:
   地区  产品  销售额_sum  销售额_mean  利润_sum  利润_mean
0  华东   A        2200      2200.0       440       440.0
1  华东   B        4100   2050.0      820       410.0
2  华南   C        3100   1550.0      660       330.0
3  华北   A        2200   1100.0      440       220.0
4  华北   B        1800   1800.0      360       360.0

代码解析:

  • 多列分组会产生多级索引(MultiIndex)。
  • 使用 as_index=False 可以将分组列保留为普通列。
  • 通过 columns 重新命名可以将多层列索引展平为单层。

提示:agg() 是分组聚合中最常用的函数之一,它不仅可以一次性计算多个统计指标,还支持自定义函数,灵活度非常高。建议在实际项目中熟练掌握它的各种用法。


Pandas 常用函数 Pandas 常用函数