You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas DataFrame中对不同列应用不同聚合函数,并执行透视表/交叉表操作?

如何在Pandas DataFrame中对不同列应用不同聚合函数,并执行透视表/交叉表操作?

嘿,我太懂这种困扰了!在SQL里我们可以轻松给不同列套上不同的聚合函数,写起来超直观:

select item, sum(a) as [sum of a], avg(b) as [avg of b], min(c) as [min of c]

但刚用Pandas的时候,是不是会有点懵——怎么在DataFrame里实现同样的操作?别担心,不管是普通的分组聚合,还是透视表、交叉表这类更复杂的结构,都有非常Pythonic的优雅写法,我来给你一步步讲清楚~

一、普通分组聚合:给不同列指定不同聚合函数

最基础的场景就是按某列分组,然后给不同的数值列分配不同的聚合逻辑。我们直接用groupby配合agg方法,传一个列名-聚合函数的映射就行,非常直白:

先构造个示例DataFrame方便演示:

import pandas as pd
import numpy as np

# 构造测试数据
df = pd.DataFrame({
    'item': ['A', 'A', 'B', 'B', 'A', 'B'],
    'a': [10, 20, 15, 25, 30, 5],
    'b': [2, 4, 3, 5, 1, 6],
    'c': [100, 200, 150, 250, 300, 50]
})

然后执行聚合操作:

# 对不同列应用不同聚合函数,同时直接定义结果列名
agg_result = df.groupby('item').agg(
    sum_of_a=('a', 'sum'),
    avg_of_b=('b', 'mean'),
    min_of_c=('c', 'min')
).reset_index()

# 查看结果
print(agg_result)

这里用了agg的命名聚合写法(Pandas 0.25+支持),直接把最终想要的列名和(原列名,聚合函数)对应起来,比先聚合再手动重命名简洁太多!输出的结果就和你SQL里写的效果完全一致。

二、透视表(Pivot Table)中的多列多聚合

如果要做透视表,同时给不同列指定不同聚合逻辑,pivot_table方法同样支持传入聚合函数字典,完美满足需求:

比如我们给测试数据加个分类列,做更复杂的透视:

# 新增分类列
df['category'] = ['X', 'Y', 'X', 'Y', 'X', 'Y']

# 透视表:按item为行,category为列,不同值列用不同聚合
pivot_result = pd.pivot_table(
    df,
    index='item',
    columns='category',
    aggfunc={
        'a': 'sum',
        'b': 'mean',
        'c': 'min'
    }
)

print(pivot_result)

执行后会得到一个多层列索引的结果,外层是原列名,内层是分类列的取值,每个单元格对应对应分组下的聚合结果,逻辑清晰一目了然。

三、交叉表(Cross Tab)风格的多聚合

交叉表一般默认是计数,但如果要给不同列用不同聚合,我们可以用groupby+unstack的组合来实现类似交叉表的结构:

# 按item和category分组聚合,再转成交叉表格式
cross_result = df.groupby(['item', 'category']).agg(
    sum_of_a=('a', 'sum'),
    avg_of_b=('b', 'mean'),
    min_of_c=('c', 'min')
).unstack('category').fillna(0)

print(cross_result)

unstack会把分组的category列转成列索引,fillna(0)用来填充没有数据的空值,最终得到的就是交叉表样式的聚合结果,完全符合需求。

备注:内容来源于stack exchange,提问作者Pythonista anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:15:27