跳至主要內容

数据分组

blacklad大约 3 分钟PythonPythonPandas

数据分组

1 介绍

数据分组是一个非常强大的功能,允许你对数据集按照某些标准进行分组,然后对每个分组单独应用某些操作。这个过程通常被称为“split-apply-combine”策略,即首先“分组”(split)数据,然后“应用”(apply)某些函数,最后将结果“组合”(combine)在一起。

分组
分组

2 数据

import pandas as pd

# 创建 DataFrame
data = {
    '姓名': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob', 'Charlie', 
             'Alice', 'Bob', 'Charlie', 'Alice', 'Bob', 'Charlie'],
    '学期': ['一', '一', '一', '二', '二', '二', 
                 '一', '一', '一', '二', '二', '二'],
    '科目': ['Math', 'Math', 'Math', 'Math', 'Math', 'Math', 
                'English', 'English', 'English', 'English', 'English', 'English'],
    '成绩': [85, 78, 92, 88, 76, 85, 90, 80, 88, 95, 82, 91]
}
df = pd.DataFrame(data)
print(df)
         姓名 学期    科目  成绩
0     Alice  一     Math  85
1       Bob  一     Math  78
2   Charlie  一     Math  92
3     Alice  二     Math  88
4       Bob  二     Math  76
5   Charlie  二     Math  85
6     Alice  一  English  90
7       Bob  一  English  80
8   Charlie  一  English  88
9     Alice  二  English  95
10      Bob  二  English  82
11  Charlie  二  English  91

3 使用 groupby

Pandas 中的分组操作主要依赖于 groupby 方法,它将数据根据某些列的值进行分组,并返回一个 DataFrameGroupBy 对象。你可以对这个对象应用各种聚合函数、过滤条件、变换操作等。

3.1 单列分组

 group = df.groupby('姓名')
 print(group)

打印 groupby 结果,可以看到返回了一个DataFrameGroupBy对象。

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f7cf6b96250>

3.2 多列分组

 df.groupby(['姓名', '科目'])

4 聚合操作

groupby 后你可以对分组数据应用各种聚合操作,如 sum()mean()count() 等。

 grouped = df.groupby(['姓名', '科目'])

4.1 分组数据的均值

对于不能求均值的学期那列,就没有显示。

mean_values = grouped.mean()
print(mean_values)
                   成绩
姓名      科目           
Alice   English  92.5
        Math     86.5
Bob     English  81.0
        Math     77.0
Charlie English  89.5
        Math     88.5

4.2 分组数据的总和

sum_values = grouped.sum()
print(sum_values)
                  成绩
姓名      科目          
Alice   English  185
        Math     173
Bob     English  162
        Math     154
Charlie English  179
        Math     177

4.3 每个分组的计数

count_values = grouped.count()
print(count_values)
                 学期  成绩
姓名      科目             
Alice   English   2   2
        Math      2   2
Bob     English   2   2
        Math      2   2
Charlie English   2   2
        Math      2   2

5 自定义函数

我们还可以对分组后的数据应用自定义函数,比如计算每个学生在每个学期的成绩的最大值与最小值之差:

def score_range(group):
    return group['成绩'].max() - group['成绩'].min()

res = grouped.apply(score_range)
print(res)
姓名       科目     
Alice    English    5
         Math       3
Bob      English    2
         Math       2
Charlie  English    3
         Math       7
dtype: int64

6 数据过滤

使用 filter 方法筛选出那些某个科目的平均分超过90分的学生:

res = grouped.filter(lambda x: x['成绩'].mean() > 90)
print(res)
      姓名 学期     科目  成绩
6  Alice  1  English  90
9  Alice  2  English  95

7 转换方法

通过 transform 对每个分组进行变换,并返回与原数据相同形状的结果。

# 首先使用 `transform` 得到每一行数据的总成绩
total = grouped['成绩'].transform('sum')

# 用每一行的成绩除以对应的总成绩
df['成绩百分比'] = df['成绩'] / total * 100
print(df)
         姓名 学期   科目  成绩  成绩百分比
0     Alice  一     Math  85  49.132948
1       Bob  一     Math  78  50.649351
2   Charlie  一     Math  92  51.977401
3     Alice  二     Math  88  50.867052
4       Bob  二     Math  76  49.350649
5   Charlie  二     Math  85  48.022599
6     Alice  一  English  90  48.648649
7       Bob  一  English  80  49.382716
8   Charlie  一  English  88  49.162011
9     Alice  二  English  95  51.351351
10      Bob  二  English  82  50.617284
11  Charlie  二  English  91  50.837989
上次编辑于:
贡献者: blacklad