pandas 分类汇总

import pandas as pd
import numpy as np

分类汇总 group by 指的是如下的一个或多个步骤的数据分组:

  • Splitting: 根据某些标准将数据分成若干组。
  • Applying: 将一个函数独立应用于每个组。
  • Combining: 将结果合并到数据结构中。

其中,拆分步骤最简单。事实上,在许多情况下,我们可能希望将数据集分成若干组,并对这些组进行处理。

在应用步骤中,我们可能希望执行以下操作之一:

  • Aggregation: 计算每组的汇总统计数据。例如计算每组的和 sum 以及平均值 means,或者数每组记录的个数。
  • Transformation: 执行一些特定于组的计算,并返回一个相似的索引对象。例如获得每组排序后的第一个数据。
  • Filtration: 根据评估为真或假的分组计算,丢弃一些分组。例如丢弃属于只有少数成员的组的数据,或者根据组和或平均值过滤数据。

分组

pandas 对象可以在其任意轴上拆分。分组的抽象定义是提供标签到组名的映射。分组需要创建 GroupBy 对象。

df = pd.DataFrame(
    [
        ("bird", "Falconiformes", 389.0),
        ("bird", "Psittaciformes", 24.0),
        ("mammal", "Carnivora", 80.2),
        ("mammal", "Primates", np.nan),
        ("mammal", "Carnivora", 58),
    ],
    index=["falcon", "parrot", "lion", "monkey", "leopard"],
    columns=("class", "order", "max_speed"),
)
df

class order max_speed
falcon bird Falconiformes 389.0
parrot bird Psittaciformes 24.0
lion mammal Carnivora 80.2
monkey mammal Primates NaN
leopard mammal Carnivora 58.0
df.groupby('class')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021B59E47F10>

axis1columns 表示按列分组,默认值为 0index 即按行分组。

df.groupby('order', axis='columns')
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021B59E47BE0>
df.groupby(['class', 'order'])
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021B576F6BB0>

应用与合并

汇总

df = pd.DataFrame(
    {
        "A": ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"],
        "B": ["one", "one", "two", "three", "two", "two", "one", "three"],
        "C": np.random.randn(8),
        "D": np.random.randn(8),
    }
)
df

A B C D
0 foo one -0.358296 2.330367
1 bar one 1.081549 -1.002115
2 foo two -0.237551 0.510146
3 bar three -1.573979 -1.366482
4 foo two -0.146734 0.273849
5 bar two -1.927644 0.645096
6 foo one 1.393947 -0.680186
7 foo three -0.036544 0.883412

GroupBy 对象后索引 column 表示需要汇总的属性,会返回一个新的 GroupBy 对象。

grouped = df.groupby('A')[['C', 'D']]

求和

grouped.sum()

C D
A
bar -2.420074 -1.723502
foo 0.614822 3.317587

平均值

grouped.mean()

C D
A
bar -0.806691 -0.574501
foo 0.122964 0.663517

中位数

grouped.median()

C D
A
bar -1.573979 -1.002115
foo -0.146734 0.510146

最小值

grouped.min()

C D
A
bar -1.927644 -1.366482
foo -0.358296 -0.680186

最大值

grouped.max()

C D
A
bar 1.081549 0.645096
foo 1.393947 2.330367

标准差

grouped.std()

C D
A
bar 1.644797 1.071799
foo 0.720271 1.096317

可以使用 agg 来使用任何可以进行汇总和统计的函数,包括用户自定义的函数。

grouped.agg(['sum', 'mean'])

C D
sum mean sum mean
A
bar -2.420074 -0.806691 -1.723502 -0.574501
foo 0.614822 0.122964 3.317587 0.663517

次序

df = pd.DataFrame({
    'Name': ['Jim', 'Jim', 'Jim', 'Pam', 'Pam'],
    'Attempt': ['First', 'Second', 'Third', 'First', 'Second'],
    'GRE Score': [298, 321, 314, 318, 330]
})
df

Name Attempt GRE Score
0 Jim First 298
1 Jim Second 321
2 Jim Third 314
3 Pam First 318
4 Pam Second 330

返回每个人最后一次 GRE 考试成绩:

df.groupby('Name')['GRE Score'].last()
Name
Jim    314
Pam    330
Name: GRE Score, dtype: int64

返回每个人第一次 GRE 考试成绩:

df.groupby('Name')['GRE Score'].first()
Name
Jim    298
Pam    318
Name: GRE Score, dtype: int64

使用 nth 可以返回第任意次 GRE 考试成绩:

df.groupby('Name')['GRE Score'].nth(1)
Name
Jim    321
Pam    330
Name: GRE Score, dtype: int64

排序

给每次 GRE 考试都加上名次。

df['Rank'] = df.groupby('Name')['GRE Score'].rank(ascending=False).astype(int)
df

Name Attempt GRE Score Rank
0 Jim First 298 3
1 Jim Second 321 1
2 Jim Third 314 2
3 Pam First 318 2
4 Pam Second 330 1

如要给每组数据都排序,建议先对原 DataFrame 对象排序,再分组。

df.sort_values('GRE Score', ascending=False).groupby('Name')['GRE Score'].first()
Name
Jim    321
Pam    330
Name: GRE Score, dtype: int64
Previous
Next