pandas 分组应用函数
看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本内容来自:https://gairuo.com
对数据进行分组后,我们就可以收获果实了,除了常见的数学统计方法,还可以使用 agg() 和 transform() 等函数进行操作。
聚合 Aggregations
.aggregate() 简写为 .agg()。它的作用是将分组后的对象给定统计方法,也支持按字段分别给定不同的统计方法。
# 所有列使用一个计算计算方法
df.groupby('team').aggregate(sum)
df.groupby('team').agg(sum)
grouped.agg(np.size)
grouped['Q1'].agg(np.mean)
## 多个计算方法
# 所有列指定多个计算方法
grouped.agg([np.sum, np.mean, np.std])
# 指定列使用多个计算方法
grouped['Q1'].agg([sum, np.mean, np.std])
# 一列使用多个计算方法
df.groupby('team').agg({'Q1': ['min', 'max'], 'Q2': 'sum'})
# 指定列名,列表是为原列和方法
df.groupby('team').Q1.agg(Mean='mean', Sum='sum')
df.groupby('team').agg(Mean=('Q1', 'mean'), Sum=('Q2', 'sum'))
df.groupby('team').agg(
Q1_max=pd.NamedAgg(column='Q1', aggfunc='max'),
Q2_min=pd.NamedAgg(column='Q2', aggfunc='min')
)
# 如果列名不是有效的 python 变量,则可以用以下方法
df.groupby('team').agg(**{
'1_max':pd.NamedAgg(column='Q1', aggfunc='max')})
# 聚合结果使用函数
# lambda/函数 所有方法都可以用
def max_min(x):
return x.max() - x.min()
# 定义函数
df.groupby('team').Q1.agg(Mean='mean',
Sum='sum',
Diff=lambda x: x.max() - x.min(),
Max_min=max_min
)
# 不同列不同的计算方法
df.groupby('team').agg({'Q1': sum, # 总和
'Q2': 'count', # 总数
'Q3':'mean', # 平均
'Q4': max}) # 最大值
# 分组对象使用函数
# 定义函数
def max_min(var):
return var.max() - var.min()
# 调用函数
df.groupby('team').agg(max_min)
关于 agg 可以查看 agg 聚合操作 详细介绍。
分组运算 Transformations
transform 类似于 agg,但不同的是它返回的是一个 df,每个会将原来的值一一替换成统计后的值,比如按组计算平均成绩,那么返回的新 df 中每个学生的成绩就是它所在组的平均成绩。
df.groupby('team').transform(max) # 最大值
df.groupby('team').transform(np.std) # 标准差
# 使用函数, 和上一个学生的差值(没有处理姓名列)
df.groupby('team').transform(lambda x: x.shift(-1))
# 函数
def score(gb):
return (gb - gb.mean()) / gb.std()*10
# 调用
grouped.transform(score)
也可以用它来做按组筛选:
# Q1 成绩大于60的组的所有成员
df[df.groupby('team').transform('mean').Q1 > 60]
如果想按组对此组的值填充一个列表值,可以用以下方法:
df.groupby('a').b.transform(lambda x: [x.to_list()]*len(x))
df['a'].map(df.groupby('a')['b'].agg(list))
更加详细的介绍可查看教程pandas transform 数值转换部分。
筛选 Filtration
filter() 筛选后后显示筛选后的原 dataframe,内容是满足组条件的所有明细:
# 值的长度都大于等于 3 的
df.groupby('team').filter(lambda x: len(x) >= 3)
# Q1成绩只要有一个大于97的组
df.groupby(['team']).filter(lambda x: (x['Q1'] > 97).any())
# 所有成员平均成绩大于 60 的组
df.groupby(['team']).filter(lambda x: (x.mean() >= 60).all())
# Q1 所有成员成绩之和超过 1060 的组
df.groupby('team').filter(lambda g: g.Q1.sum() > 1060)
关于 filter 的详细介绍,可以查阅:pandas filter 筛选标签。
函数 apply
对对象应用函数进行处理,以下是对所有的值乘以2:
df.groupby('team').apply(lambda x: x*2)
实现 hive sql 中的 collect_list:
df.groupby('team').apply(lambda x: x['name'].to_list())
# 输出一个 np.array
df.groupby('team').apply(np.array)
我们有个需求,是看每组 Q1 成绩的最高的前五个:
# 各组 Q1(为参数) 成绩的前五个
def first_5(df_, c):
return df_[c].sort_values(ascending = False).head()
# 调用函数
df.set_index('name').groupby('team').apply(first_5, 'Q1')
# group_keys 可以使分组字段不做为索引
(df.set_index('name')
.groupby('team', group_keys=False)
.apply(first_5, 'Q1')
)
可以使用 Series 来使用,索引是列表,值是统计方法。以下使用 lambda 构造一个 Series:
(df.groupby('team')
.apply(lambda x: pd.Series({
'Q1_sum' : x['Q1'].sum(),
'Q1_max' : x['Q1'].max(),
'Q2_mean' : x['Q2'].mean(),
'Q4_prodsum' : (x['Q4'] * x['Q4']).sum()
}))
)
# 可以定义一个函数
def f_mi(x):
d = []
d.append(x['Q1'].sum())
d.append(x['Q2'].max())
d.append(x['Q3'].mean())
d.append((x['Q4'] * x['Q4']).sum())
return pd.Series(d, index=[['Q1', 'Q2', 'Q3', 'Q4'],
['sum', 'max', 'mean', 'prodsum']])
# 使用函数
df.groupby('team').apply(f_mi)
'''
Q1 Q2 Q3 Q4
sum max mean prodsum
team
A 1066.0 87.0 51.470588 51129.0
B 975.0 99.0 54.636364 76696.0
C 1056.0 96.0 48.545455 68571.0
D 860.0 97.0 65.315789 87473.0
E 963.0 98.0 44.050000 71317.0
'''
不过以上建议在复杂的需求场景下使用。一行代码可以按分组导出 Excel 文件:
# 一个分组导出一个 Excel 文件
(
df.groupby('team')
.apply(lambda x: x.to_excel(f'{x.name}.xlsx'))
)
要注意的是,name 是分组名,不是 name 列,要取同名列的话可以使用切片 x['name']。可以查看此案例 pandas 按分组一个分组导出一个文件 。
关于 apply 的详细介绍,可以查阅:pandas apply 函数应用。
管道方法
类似于 df 的管道方法,分组对象的管道方法是接收之前的分组对象将同组里的所有数据应用在方法中。
# 最大值和最小值之间的差值
df.groupby('team').pipe(lambda x: x.max() - x.min())
# 使用函数
def mean_diff(x):
return x.get_group('A').mean() - x.get_group('B').mean()
# 以上定义了 A 组和 B 组平均值的差值
df.groupby('team').pipe(mean_diff)
关于 pipe 的详细介绍,可以查阅:pandas pipe 管道方法。
参考
https://github.com/pandas-dev/pandas/issues/25457
相关内容
pandas习题 182:每组最大绩效的员工完整记录
2025-09-02 14:58:36
pandas习题 181:保留连续 3 天无缺失的销售渠道
2025-09-02 12:33:41
pandas习题 180:不同列用不同函数聚合
2025-09-02 11:57:52
pandas习题 179:分组后 agg() 自定义函数
2025-09-02 11:33:45
pandas习题 151:transform() 补缺失值并做 z-score 标准化
2025-08-26 17:11:01
pandas 组内排序并保持小计位置
2024-02-15 23:21:43
pandas 按组跳过指定值标记序号
2024-01-30 07:37:18
pandas 按组生成分数表示数据
2022-02-12 14:03:59
pandas 计算每名客户够最低还款额日期
2021-12-03 23:55:22
pandas 删除连续6个以上小于0.4的值
2021-09-18 21:17:30
pandas 计算分组后多个列表中的不重复值
2021-05-19 15:01:52
pandas 实现 group_concat 分组列表连接功能
2021-04-08 14:22:19
pandas 分组并值为组成员列表的字典
2021-02-28 09:26:05
pandas 将分组名称插入本组内容之前
2021-01-21 12:08:46
pandas 按组填充缺失值
2020-12-16 12:29:32
< 分组聚合统计
pandas 教程
分组对象的操作 >
更新时间:2023-04-15 15:36:38
标签:pandas
分组
函数
最新发布
-
如何绘画水果:工具准备与技巧详解?
2025-10-09 21:28:44 -
华为手机辅助服务自动关闭解决办法
2025-06-15 21:29:34 -
晚吹 - 怨女俱樂部
2025-08-06 03:00:47 -
淘宝刷接单平台有哪些?刷手需要注意什么?
2025-05-29 13:17:59 -
小静静攻略【小静静获取攻略】任务时间:10天
2025-05-16 15:11:47 -
你能通《生化奇兵:无限》多久 ▷➡️
2025-09-23 03:16:31 -
卧龙吟袁术(卧龙吟名门袁绍技能)
2025-05-08 20:12:35 -
魔兽世界竞技场
2025-07-30 16:58:55 -
如何攻略皇后(重生)
2025-05-07 23:49:06 -
oppor7c手机
2025-07-09 09:27:11