groupby结合agg和transform使用
本文介绍的是分组groupby分组之后如何使用agg和transform
模拟数据
代码语言:javascript复制import pandas as pd
import numpy as np
代码语言:javascript复制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
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
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 单个字段 单个聚合
求解每个人的总薪资金额:
代码语言:javascript复制total_salary = df.groupby("employees")["salary"].sum().reset_index()
total_salary
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
使用agg也能够实现上面的效果:
代码语言:javascript复制df.groupby("employees").agg({"salary":"sum"}).reset_index()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
df.groupby("employees").agg({"salary":np.sum}).reset_index()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | salary | |
---|---|---|
0 | 小周 | 873 |
1 | 小张 | 2741 |
2 | 小明 | 1851 |
3 | 小王 | 3430 |
groupby 单个字段 多个聚合
求解每个人的总薪资金额和薪资的平均数:
方法1:使用groupby merge
代码语言:javascript复制mean_salary = df.groupby("employees")["salary"].mean().reset_index()
mean_salary
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | salary | |
---|---|---|
0 | 小周 | 873.000000 |
1 | 小张 | 913.666667 |
2 | 小明 | 925.500000 |
3 | 小王 | 857.500000 |
然后将上面的两个结果进行组合;在合并之前为了字段的名字更加的直观,我们重命名下:
代码语言:javascript复制total_salary.rename(columns={"employees":"total_salary"})
mean_salary.columns = ["employees","mean_salary"]
代码语言:javascript复制total_mean = total_salary.merge(mean_salary)
total_mean
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | salary | mean_salary | |
---|---|---|---|
0 | 小周 | 873 | 873.000000 |
1 | 小张 | 2741 | 913.666667 |
2 | 小明 | 1851 | 925.500000 |
3 | 小王 | 3430 | 857.500000 |
方法2:使用groupby agg
代码语言:javascript复制total_mean = df.groupby("employees")
.agg(total_salary=("salary", "sum"),
mean_salary=("salary", "mean"))
.reset_index()
total_mean
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | total_salary | mean_salary | |
---|---|---|---|
0 | 小周 | 873 | 873.000000 |
1 | 小张 | 2741 | 913.666667 |
2 | 小明 | 1851 | 925.500000 |
3 | 小王 | 3430 | 857.500000 |
groupby 多个字段 单个聚合
针对多个字段的同时聚合:
代码语言:javascript复制df.groupby(["employees","time"])["salary"].sum().reset_index()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
employees | time | salary | |
---|---|---|---|
0 | 小周 | 上半年 | 873 |
1 | 小张 | 上半年 | 1930 |
2 | 小张 | 下半年 | 811 |
3 | 小明 | 上半年 | 1851 |
4 | 小王 | 上半年 | 841 |
5 | 小王 | 下半年 | 2589 |
groupby 多个字段 多个聚合
使用的方法是:
代码语言:javascript复制agg(’新列名‘=(’原列名‘, ’统计函数/方法‘))
代码语言:javascript复制df.groupby(["employees","time"])
.agg(total_salary=("salary", "sum"),
mean_salary=("salary", "mean"),
total_score=("score", "sum")
)
.reset_index()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } <pre><code>.dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </code></pre>
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 |