分类汇总
分类汇总
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 0x000001BC34299A10>
按多个字段分组。
df.groupby(['class', 'order'])<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001BC3427E710>
通常一张数据表每一行表示一条记录,每一列表示一个字段。因而分类汇总是针对字段,对每条记录(按行)进行分组。如果确实有按列进行分组的需求,将 DataFrame 对象转置即可。
应用与合并
汇总
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.106162 | -0.093786 |
| 1 | bar | one | -0.179389 | 2.213905 |
| 2 | foo | two | -0.190954 | 0.082038 |
| 3 | bar | three | 0.312979 | 1.034273 |
| 4 | foo | two | 1.052136 | -0.130627 |
| 5 | bar | two | -1.220164 | 1.215908 |
| 6 | foo | one | -0.926031 | -1.477368 |
| 7 | foo | three | 0.157087 | 1.622384 |
GroupBy 对象后索引 column 表示需要汇总的属性,会返回一个新的 GroupBy 对象。
grouped = df.groupby('A')[['C', 'D']]求和
grouped.sum()| C | D | |
|---|---|---|
| A | ||
| bar | -1.086574 | 4.464086 |
| foo | 0.198399 | 0.002641 |
平均值
grouped.mean()| C | D | |
|---|---|---|
| A | ||
| bar | -0.362191 | 1.488029 |
| foo | 0.039680 | 0.000528 |
中位数
grouped.median()| C | D | |
|---|---|---|
| A | ||
| bar | -0.179389 | 1.215908 |
| foo | 0.106162 | -0.093786 |
最小值
grouped.min()| C | D | |
|---|---|---|
| A | ||
| bar | -1.220164 | 1.034273 |
| foo | -0.926031 | -1.477368 |
最大值
grouped.max()| C | D | |
|---|---|---|
| A | ||
| bar | 0.312979 | 2.213905 |
| foo | 1.052136 | 1.622384 |
标准差
grouped.std()| C | D | |
|---|---|---|
| A | ||
| bar | 0.782748 | 0.635154 |
| foo | 0.712226 | 1.100833 |
可以使用 agg 来使用任何可以进行汇总和统计的函数,包括用户自定义的函数。
grouped.agg(['sum', 'mean'])| C | D | |||
|---|---|---|---|---|
| sum | mean | sum | mean | |
| A | ||||
| bar | -1.086574 | -0.362191 | 4.464086 | 1.488029 |
| foo | 0.198399 | 0.039680 | 0.002641 | 0.000528 |
次序
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)1 321
4 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