groupby
是数据分析中一个非常强大的操作,可以根据指定的规则将数据拆分成多个组,并对每个组进行聚合、转换或过滤等操作。我们逐个解释这些参数的作用,并通过数值举例进行说明。
参数解释
-
by:分组依据
by
参数指定了分组的依据,可以是:- 函数:对于数据的每个索引(或列)应用该函数,生成一个新的值,根据这些值进行分组。
- 字典 或 Series:可以通过字典或
Series
来指定分组的规则。字典的键是原数据的索引,值是分组的标签。 - ndarray:可以直接用数组来指定每一行或列所属的分组。
-
axis:拆分的方向
axis
参数指定了操作的方向:axis=0
:按行分组(默认)。axis=1
:按列分组。
-
level:多层索引的分组层级
level
参数适用于多层索引(MultiIndex
)。可以指定按某个层级或多个层级进行分组。
-
as_index:是否将分组键作为索引
- 默认值是
True
,即返回的结果会把分组的标签作为新的索引。 - 如果设置为
False
,则不会将分组标签作为索引,而是作为普通列显示。
- 默认值是
-
sort:是否对分组进行排序
- 默认值是
True
,表示对每个组的标签进行排序。 - 如果设置为
False
,则分组内的顺序与原数据中的顺序一致,通常会提高性能。
- 默认值是
-
group_keys:是否将组键添加到结果中
- 默认值是
True
,即返回的结果会包含分组键,标明每个组的来源。 - 如果为
False
,则不添加组键。
- 默认值是
-
observed:分类数据的显示方式
- 当分组是分类数据时,
observed=True
会只显示有实际数据的分类值,而不会显示所有的分类值(包括那些没有数据的分类)。 - 如果设置为
False
,则会显示所有可能的分类值。
- 当分组是分类数据时,
-
dropna:是否删除包含 NA 的组
- 如果为
True
,则包含 NA 值的组会被删除。 - 如果为
False
,NA 值会被当作一个组处理。
- 如果为
举例说明
假设我们有以下的 DataFrame
和 Series
数据:
import pandas as pd
# 创建一个 DataFrame
df = pd.DataFrame({
'A': [1, 2, 2, 3, 4, 5],
'B': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
'C': [10, 20, 30, 40, 50, 60]
})
输出:
1. by
:按列分组
我们可以按照 B
列的值来对 df
进行分组:
grouped = df.groupby('B')
for name, group in grouped:
print(f"Group: {name}")
print(group)
print(grouped.sum())
输出:
2. axis
:按列分组
如果你想按列分组而不是按行分组,可以设置 axis=1
:
grouped = df.groupby(axis=1, level=0)
for name, group in grouped:
print(f"Group: {name}")
print(group)
这个例子不太常见,通常 groupby
更常用于行分组,但这会按列的方式分组。输出中会提醒不建议这么做:
3. level
:多层索引分组
假设你有一个多层索引的 DataFrame
,你可以按指定的层级进行分组。
# 创建一个 MultiIndex DataFrame
index = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1), ('b', 2)],
names=['letter', 'number'])
df_multi = pd.DataFrame({
'A': [1, 2, 3, 4],
'B': [5, 6, 7, 8]
}, index=index)
# 按 'letter' 层级进行分组
grouped = df_multi.groupby(level='letter')
for name, group in grouped:
print(f"Group: {name}")
print(group)
输出:
Group: a
A B
letter number
a 1 1 5
2 2 6
Group: b
A B
letter number
b 1 3 7
2 4 8
更多例子
4. as_index
:是否将分组键作为索引
我们可以设置 as_index=False
,让分组键不成为新的索引。
grouped = df.groupby('B', as_index=False)
print(grouped.sum())
输出:
5. sort
:是否排序分组
如果 sort=False
,则按照原始数据的顺序进行分组,而不是按照分组键的顺序排序:
grouped = df.groupby('B', sort=False)
for name, group in grouped:
print(f"Group: {name}")
print(group)
输出:
Group: X
A B C
0 1 X 10
2 2 X 30
4 4 X 50
Group: Y
A B C
1 2 Y 20
3 3 Y 40
5 5 Y 60
6. dropna
:是否删除包含NA值的组
如果你有一些 NA 值,并设置 dropna=True
,它会删除包含 NA 的组:
df_with_na = pd.DataFrame({
'A': [1, 2, 3, None, 5],
'B': ['X', 'Y', 'X', 'Y', 'X'],
'C': [10, 20, 30, 40, None]
})
grouped = df_with_na.groupby('B', dropna=True)
print(grouped.sum())
输出:
总结
groupby
是根据某些规则将数据拆分为多个组,然后对每个组进行计算。可以根据by
、axis
、level
等参数灵活控制分组的方式。- 常用的操作包括按列分组、按层级分组、控制排序和是否删除包含 NA 值的组。