Pandas GroupBy:强大的数据分组与聚合工具

Pandas GroupBy:强大的数据分组与聚合工具

参考:pandas groupby

Pandas GroupBy 是 Pandas 库中一个非常强大和灵活的功能,它允许我们对数据进行分组和聚合操作。通过 GroupBy,我们可以轻松地对大型数据集进行复杂的分析和计算。本文将详细介绍 Pandas GroupBy 的使用方法、常见操作以及一些高级技巧。

1. GroupBy 的基本概念

GroupBy 操作的核心思想是将数据按照某个或某些列的值进行分组,然后对每个分组应用特定的操作。这个过程可以分为三个步骤:

  1. 分割(Split):根据指定的键将数据分成若干组。
  2. 应用(Apply):对每个分组应用指定的函数或操作。
  3. 组合(Combine):将操作结果组合成一个新的数据结构。

让我们通过一个简单的例子来理解 GroupBy 的基本用法:

import pandas as pd

# 创建示例数据
data = {
    'website': ['pandasdataframe.com', 'pandasdataframe.com', 'pandasdataframe.com', 'pandasdataframe.com'],
    'category': ['A', 'B', 'A', 'B'],
    'visits': [100, 150, 200, 250]
}
df = pd.DataFrame(data)

# 按 category 列进行分组,并计算 visits 列的平均值
result = df.groupby('category')['visits'].mean()

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

在这个例子中,我们首先创建了一个包含网站访问数据的 DataFrame。然后,我们使用 groupby() 方法按 ‘category’ 列进行分组,并计算每个分组中 ‘visits’ 列的平均值。

2. GroupBy 对象的创建

创建 GroupBy 对象的最常见方法是使用 DataFrame 的 groupby() 方法。这个方法可以接受多种类型的参数:

2.1 单列分组

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 5,
    'category': ['A', 'B', 'A', 'C', 'B'],
    'visits': [100, 150, 200, 250, 300]
}
df = pd.DataFrame(data)

grouped = df.groupby('category')

在这个例子中,我们按 ‘category’ 列进行分组。

2.2 多列分组

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'subcategory': ['X', 'X', 'Y', 'Y', 'Z', 'Z'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

grouped = df.groupby(['category', 'subcategory'])

这个例子展示了如何按多个列进行分组。我们同时使用 ‘category’ 和 ‘subcategory’ 列作为分组键。

2.3 使用函数进行分组

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 5,
    'value': [10, 20, 30, 40, 50]
}
df = pd.DataFrame(data)

grouped = df.groupby(lambda x: 'Group A' if df.loc[x, 'value'] < 30 else 'Group B')

在这个例子中,我们使用一个 lambda 函数作为分组键。该函数根据 ‘value’ 列的值将数据分为两组。

3. 常用的 GroupBy 操作

3.1 聚合操作

聚合操作是 GroupBy 最常用的功能之一。我们可以使用内置的聚合函数或自定义函数来对分组数据进行计算。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

# 使用内置聚合函数
result = df.groupby('category').agg({
    'visits': ['sum', 'mean', 'max', 'min']
})

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

在这个例子中,我们对 ‘visits’ 列使用了多个聚合函数:求和、平均值、最大值和最小值。

3.2 转换操作

转换操作允许我们对分组数据应用函数,并返回与原始数据具有相同索引的结果。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

# 计算每个分组的累积和
result = df.groupby('category')['visits'].transform('cumsum')

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何使用 transform() 方法计算每个分组的累积和。

3.3 过滤操作

过滤操作允许我们根据某些条件选择或排除某些分组。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'C', 'A', 'B', 'C'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

# 选择平均访问量大于 200 的分组
result = df.groupby('category').filter(lambda x: x['visits'].mean() > 200)

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

在这个例子中,我们使用 filter() 方法选择平均访问量大于 200 的分组。

4. 高级 GroupBy 技巧

4.1 多级索引的处理

当使用多列进行分组时,结果会产生多级索引。我们可以使用 unstack() 方法将多级索引转换为更易读的形式。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 8,
    'category': ['A', 'A', 'B', 'B'] * 2,
    'subcategory': ['X', 'Y'] * 4,
    'visits': [100, 150, 200, 250, 300, 350, 400, 450]
}
df = pd.DataFrame(data)

result = df.groupby(['category', 'subcategory'])['visits'].sum().unstack()

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何使用 unstack() 方法将多级索引转换为更易读的表格形式。

4.2 自定义聚合函数

除了使用内置的聚合函数,我们还可以定义自己的聚合函数。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

def range_diff(x):
    return x.max() - x.min()

result = df.groupby('category')['visits'].agg(range_diff)

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

在这个例子中,我们定义了一个自定义函数 range_diff,用于计算每个分组中最大值和最小值的差。

4.3 分组迭代

GroupBy 对象支持迭代,这允许我们对每个分组单独进行操作。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'visits': [100, 150, 200, 250, 300, 350]
}
df = pd.DataFrame(data)

for name, group in df.groupby('category'):
    print(f"Category: {name}")
    print(group)
    print()

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何遍历 GroupBy 对象的每个分组。

4.4 分组操作与其他 Pandas 功能的结合

GroupBy 可以与其他 Pandas 功能结合使用,例如重采样和窗口函数。

import pandas as pd
import numpy as np

# 创建一个时间序列数据
dates = pd.date_range('20230101', periods=12)
data = {
    'website': ['pandasdataframe.com'] * 12,
    'date': dates,
    'category': ['A', 'B'] * 6,
    'value': np.random.randn(12)
}
df = pd.DataFrame(data)

# 按月重采样并计算每个类别的平均值
result = df.set_index('date').groupby('category')['value'].resample('M').mean()

print(result)

这个例子展示了如何将 GroupBy 与时间序列重采样结合使用。

5. GroupBy 的性能优化

在处理大型数据集时,GroupBy 操作可能会变得很慢。以下是一些提高 GroupBy 性能的技巧:

5.1 使用 categoricals

将分组键转换为 categorical 类型可以显著提高 GroupBy 的性能。

import pandas as pd
import numpy as np

# 创建一个大型数据集
n = 1000000
data = {
    'website': ['pandasdataframe.com'] * n,
    'category': np.random.choice(['A', 'B', 'C'], n),
    'value': np.random.randn(n)
}
df = pd.DataFrame(data)

# 将 category 列转换为 categorical 类型
df['category'] = df['category'].astype('category')

# 执行 GroupBy 操作
result = df.groupby('category')['value'].mean()

print(result)

在这个例子中,我们将 ‘category’ 列转换为 categorical 类型,这可以加速后续的 GroupBy 操作。

5.2 使用 numba 加速

对于自定义聚合函数,我们可以使用 numba 来加速计算。

import pandas as pd
import numpy as np
from numba import jit

@jit(nopython=True)
def custom_agg(values):
    return np.mean(values) * np.std(values)

data = {
    'website': ['pandasdataframe.com'] * 1000000,
    'category': np.random.choice(['A', 'B', 'C'], 1000000),
    'value': np.random.randn(1000000)
}
df = pd.DataFrame(data)

result = df.groupby('category')['value'].agg(custom_agg)

print(result)

在这个例子中,我们使用 numba 的 @jit 装饰器来加速自定义聚合函数。

6. GroupBy 的常见问题和解决方案

6.1 处理缺失值

GroupBy 操作默认会排除缺失值。如果我们想包含缺失值,可以使用 dropna=False 参数。

import pandas as pd
import numpy as np

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', np.nan],
    'value': [1, 2, 3, 4, 5, 6]
}
df = pd.DataFrame(data)

# 包含缺失值的分组
result = df.groupby('category', dropna=False)['value'].sum()

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何在 GroupBy 操作中包含缺失值。

6.2 处理大型数据集

对于非常大的数据集,我们可以使用 chunksize 参数来分块处理数据。

import pandas as pd
import numpy as np

# 创建一个大型数据集
n = 10000000
data = {
    'website': ['pandasdataframe.com'] * n,
    'category': np.random.choice(['A', 'B', 'C'], n),
    'value': np.random.randn(n)
}
df = pd.DataFrame(data)

# 使用 chunksize 分块处理数据
result = pd.DataFrame()
for chunk in df.groupby('category', as_index=False, sort=False).apply(lambda x: x.sample(n=1000)):
    result = result.append(chunk)

print(result.head())

这个例子展示了如何使用 chunksize 参数来处理大型数据集。

7. GroupBy 与其他 Pandas 功能的结合

7.1 GroupBy 与 merge

我们可以将 GroupBy 的结果与原始数据框进行合并。

import pandas as pd

data = {
    'website': ['pandasdataframe.com'] * 6,
    'category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'subcategory': ['X', 'X', 'Y', 'Y', 'Z', 'Z'],
    'value': [1, 2, 3, 4, 5, 6]
}
df = pd.DataFrame(data)

# 计算每个类别的平均值
category_means = df.groupby('category')['value'].mean().reset_index()

# 将结果与原始数据框合并
result = pd.merge(df, category_means, on='category', suffixes=('', '_mean'))

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何将 GroupBy 的结果与原始数据框进行合并,从而为每个记录添加分组的平均值。

7.2 GroupBy 与 pivot_table

pivot_table 函数实际上是 GroupBy 操作的一种高级封装,它可以更方便地创建交叉表。

import pandas as pd
import numpy as np

data = {
    'website': ['pandasdataframe.com'] * 12,
    'date': pd.date_range('2023-01-01', periods=12),
    'category': ['A', 'B', 'C'] * 4,
    'value': np.random.randn(12)
}
df = pd.DataFrame(data)

# 使用 pivot_table 创建交叉表
result = pd.pivot_table(df, values='value', index='date', columns='category', aggfunc='sum')

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何使用 pivot_table 函数创建一个交叉表,其中行是日期,列是类别,值是 ‘value’ 列的总和。

8. GroupBy 的高级应用

8.1 滚动窗口计算

我们可以结合 GroupBy 和滚动窗口函数来执行更复杂的时间序列分析。

import pandas as pd
import numpy as np

data = {
    'website': ['pandasdataframe.com'] * 100,
    'date': pd.date_range('2023-01-01', periods=100),
    'category': np.random.choice(['A', 'B'], 100),
    'value': np.random.randn(100)
}
df = pd.DataFrame(data)

# 按类别分组,然后计算30天滚动平均
result = df.set_index('date').groupby('category')['value'].rolling(window='30D').mean()

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何按类别分组,然后计算每个类别的30天滚动平均值。

8.2 分组差分

我们可以使用 GroupBy 来计算分组内的差分。

import pandas as pd
import numpy as np

data = {
    'website': ['pandasdataframe.com'] * 12,
    'date': pd.date_range('2023-01-01', periods=12),
    'category': ['A', 'B'] * 6,
    'value': np.random.randn(12)
}
df = pd.DataFrame(data)

# 计算每个类别内的差分
result = df.set_index('date').groupby('category')['value'].diff()

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何计算每个类别内的差分,这在分析时间序列数据时非常有用。

8.3 分组排序

我们可以使用 GroupBy 来实现分组内的排序。

import pandas as pd
import numpy as np

data = {
    'website': ['pandasdataframe.com'] * 10,
    'category': ['A', 'B'] * 5,
    'value': np.random.randn(10)
}
df = pd.DataFrame(data)

# 在每个类别内按 value 列降序排序
result = df.sort_values('value', ascending=False).groupby('category').head(2)

print(result)

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何在每个类别内按 ‘value’ 列降序排序,并选择每个类别的前两行。

9. GroupBy 与数据可视化

GroupBy 的结果通常可以直接用于数据可视化,这可以帮助我们更好地理解数据。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = {
    'website': ['pandasdataframe.com'] * 100,
    'date': pd.date_range('2023-01-01', periods=100),
    'category': np.random.choice(['A', 'B', 'C'], 100),
    'value': np.random.randn(100)
}
df = pd.DataFrame(data)

# 按类别和日期分组,计算平均值
result = df.groupby(['category', pd.Grouper(key='date', freq='W')])['value'].mean().unstack()

# 绘制折线图
result.plot(kind='line')
plt.title('Weekly Average Value by Category')
plt.xlabel('Date')
plt.ylabel('Average Value')
plt.show()

Output:

Pandas GroupBy:强大的数据分组与聚合工具

这个例子展示了如何将 GroupBy 的结果用于创建折线图,显示每个类别的每周平均值。

10. 结论

Pandas GroupBy 是一个强大的工具,它允许我们以灵活和高效的方式对数据进行分组和聚合。通过本文介绍的各种技巧和示例,我们可以看到 GroupBy 在数据分析中的广泛应用。

从基本的分组和聚合操作,到高级的时间序列分析和性能优化,GroupBy 为我们提供了丰富的功能。结合其他 Pandas 功能,如合并、透视表和可视化,我们可以进行更复杂和深入的数据分析。

在实际应用中,熟练运用 GroupBy 可以大大提高数据处理和分析的效率。无论是处理金融数据、用户行为数据,还是其他类型的结构化数据,GroupBy 都是一个不可或缺的工具。

随着数据量的不断增长和分析需求的日益复杂,掌握 GroupBy 的各种用法将使你在数据分析领域更具竞争力。希望本文能够帮助你更好地理解和使用 Pandas GroupBy,并在实际工作中充分发挥其威力。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程