如何在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
相关产品推荐
相关产品推荐

