【Python】Pandas技巧:groupby+agg/transform
公众号:尤而小屋
作者:Peter
编辑:Peter
本文介绍的是分组groupby分组之后如何使用agg和transform
模拟数据
import pandas as pd
import numpy as np
employees = ["小明","小周","小孙","小王","小张"] # 5位员工
time = ["上半年", "下半年"]
df=pd.DataFrame({
"employees":np.random.choice(employees,10), # 在员工中重复选择10次
# 另一种写法
#"employees":[employees[x] for x in np.random.randint(0,len(employees),10)],
"time":np.random.choice(time,10),
"salary":np.random.randint(800,1000,10), # 800-1000之间的薪资选择10个数值
"score":np.random.randint(6,12,10) # 6-11的分数选择10个
})
df
employees | time | salary | score | |
---|---|---|---|---|
0 | 小周 | 上半年 | 873 | 11 |
1 | 小王 | 下半年 | 818 | 10 |
2 | 小王 | 下半年 | 804 | 6 |
3 | 小张 | 下半年 | 811 | 7 |
4 | 小张 | 上半年 | 955 | 10 |
5 | 小张 | 上半年 | 975 | 11 |
6 | 小明 | 上半年 | 858 | 9 |
7 | 小明 | 上半年 | 993 | 11 |
8 | 小王 | 上半年 | 841 | 8 |
9 | 小王 | 下半年 | 967 | 7 |
groupby+单个字段+单个聚合
求解每个人的总薪资金额:
total_salary = df.groupby("employees")["salary"].sum().reset_index()
total_salary
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
使用agg也能够实现上面的效果:
df.groupby("employees").agg({"salary":"sum"}).reset_index()
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
df.groupby("employees").agg({"salary":np.sum}).reset_index()
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
groupby+单个字段+多个聚合
求解每个人的总薪资金额和薪资的平均数:
方法1:使用groupby+merge
mean_salary = df.groupby("employees")["salary"].mean().reset_index()
mean_salary
employees | salary | |
---|---|---|
0 | 小周 | 873.000000 |
1 | 小张 | 913.666667 |
2 | 小明 | 925.500000 |
3 | 小王 | 857.500000 |
然后将上面的两个结果进行组合;在合并之前为了字段的名字更加的直观,我们重命名下:
total_salary.rename(columns={"employees":"total_salary"})
mean_salary.columns = ["employees","mean_salary"]
total_mean = total_salary.merge(mean_salary)
total_mean
employees | salary | mean_salary | |
---|---|---|---|
0 | 小周 | 873 | 873.000000 |
1 | 小张 | 2741 | 913.666667 |
2 | 小明 | 1851 | 925.500000 |
3 | 小王 | 3430 | 857.500000 |
方法2:使用groupby+agg
total_mean = df.groupby("employees")\
.agg(total_salary=("salary", "sum"),
mean_salary=("salary", "mean"))\
.reset_index()
total_mean
employees | total_salary | mean_salary | |
---|---|---|---|
0 | 小周 | 873 | 873.000000 |
1 | 小张 | 2741 | 913.666667 |
2 | 小明 | 1851 | 925.500000 |
3 | 小王 | 3430 | 857.500000 |
groupby+多个字段+单个聚合
针对多个字段的同时聚合:
df.groupby(["employees","time"])["salary"].sum().reset_index()
employees | time | salary | |
---|---|---|---|
0 | 小周 | 上半年 | 873 |
1 | 小张 | 上半年 | 1930 |
2 | 小张 | 下半年 | 811 |
3 | 小明 | 上半年 | 1851 |
4 | 小王 | 上半年 | 841 |
5 | 小王 | 下半年 | 2589 |
# 使用agg来实现
df.groupby(["employees","time"]).agg({"salary":"sum"}).reset_index()
employees | time | salary | |
---|---|---|---|
0 | 小周 | 上半年 | 873 |
1 | 小张 | 上半年 | 1930 |
2 | 小张 | 下半年 | 811 |
3 | 小明 | 上半年 | 1851 |
4 | 小王 | 上半年 | 841 |
5 | 小王 | 下半年 | 2589 |
groupby+多个字段+多个聚合
使用的方法是:
agg(’新列名‘=(’原列名‘, ’统计函数/方法‘))
df.groupby(["employees","time"])\
.agg(total_salary=("salary", "sum"),
mean_salary=("salary", "mean"),
total_score=("score", "sum")
)\
.reset_index()
employees | time | total_salary | mean_salary | total_score | |
---|---|---|---|---|---|
0 | 小周 | 上半年 | 873 | 873.0 | 11 |
1 | 小张 | 上半年 | 1930 | 965.0 | 21 |
2 | 小张 | 下半年 | 811 | 811.0 | 7 |
3 | 小明 | 上半年 | 1851 | 925.5 | 20 |
4 | 小王 | 上半年 | 841 | 841.0 | 8 |
5 | 小王 | 下半年 | 2589 | 863.0 | 23 |
groupby+transform
关于transform函数的使用请参考(建议一定要看):Pandas高阶函数transform使用机制
一张关于transform函数的备忘录:
往期精彩回顾
适合初学者入门人工智能的路线及资料下载 (图文+视频)机器学习入门系列下载 机器学习及深度学习笔记等资料打印 《统计学习方法》的代码复现专辑 机器学习交流qq群955171419,加入微信群请扫码
评论