Pandas分组groupby结合agg-transform

2023-08-25 11:47:13 浏览数 (2)

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

代码语言:javascript复制
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

代码语言:javascript复制
# 使用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

0 人点赞