Pandas GroupBy 分组操作及获取分组详解

Pandas GroupBy 分组操作及获取分组详解

参考:pandas groupby get groups

Pandas是Python中用于数据分析和处理的强大库,其中GroupBy操作是一个非常重要的功能。本文将详细介绍Pandas中的GroupBy操作以及如何获取分组结果,帮助读者更好地理解和使用这一功能。

1. GroupBy的基本概念

GroupBy操作允许我们将数据按照某个或某些列进行分组,然后对每个分组进行聚合操作。这在数据分析中非常有用,可以帮助我们快速了解数据的分布和特征。

以下是一个简单的GroupBy示例:

import pandas as pd

# 创建示例数据
data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Alice', 'Bob'],
    'age': [25, 30, 35, 28, 25, 31],
    'city': ['New York', 'London', 'Paris', 'Tokyo', 'New York', 'London'],
    'score': [85, 92, 78, 95, 88, 90]
}
df = pd.DataFrame(data)

# 按name列进行分组并计算平均分数
grouped = df.groupby('name')['score'].mean()
print(grouped)

Output:

Pandas GroupBy 分组操作及获取分组详解

在这个例子中,我们创建了一个包含姓名、年龄、城市和分数的DataFrame,然后按照姓名进行分组,并计算每个人的平均分数。

2. 创建GroupBy对象

要进行GroupBy操作,首先需要创建一个GroupBy对象。有多种方式可以创建GroupBy对象:

2.1 使用单个列进行分组

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': ['2023-01-01', '2023-01-02', '2023-01-01', '2023-01-03', '2023-01-02', '2023-01-03']
}
df = pd.DataFrame(data)

# 按product列进行分组
grouped = df.groupby('product')
print(type(grouped))

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用单个列(product)创建GroupBy对象。

2.2 使用多个列进行分组

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'category': ['X', 'Y', 'X', 'Z', 'Y', 'Z'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': ['2023-01-01', '2023-01-02', '2023-01-01', '2023-01-03', '2023-01-02', '2023-01-03']
}
df = pd.DataFrame(data)

# 按product和category列进行分组
grouped = df.groupby(['product', 'category'])
print(type(grouped))

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用多个列(product和category)创建GroupBy对象。

2.3 使用函数进行分组

import pandas as pd

# 创建示例数据
data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'age': [25, 30, 35, 28, 22],
    'score': [85, 92, 78, 95, 88]
}
df = pd.DataFrame(data)

# 使用函数进行分组
grouped = df.groupby(lambda x: 'pandasdataframe.com_' + ('Young' if df.loc[x, 'age'] < 30 else 'Old'))
print(type(grouped))

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用自定义函数进行分组。在这里,我们根据年龄将人分为”Young”和”Old”两组。

3. 获取分组信息

创建GroupBy对象后,我们可以通过多种方式获取分组信息:

3.1 使用groups属性

import pandas as pd

# 创建示例数据
data = {
    'category': ['A', 'B', 'A', 'C', 'B', 'A'],
    'value': [10, 20, 15, 30, 25, 18]
}
df = pd.DataFrame(data)

# 按category列进行分组
grouped = df.groupby('category')

# 获取分组信息
groups = grouped.groups
print(groups)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用groups属性获取分组信息。返回的结果是一个字典,键是分组的值,值是对应的索引。

3.2 使用get_group()方法

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 按product列进行分组
grouped = df.groupby('product')

# 获取特定分组的数据
group_a = grouped.get_group('A')
print(group_a)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用get_group()方法获取特定分组的数据。

3.3 遍历分组

import pandas as pd

# 创建示例数据
data = {
    'category': ['X', 'Y', 'X', 'Z', 'Y', 'X'],
    'value': [10, 20, 15, 30, 25, 18]
}
df = pd.DataFrame(data)

# 按category列进行分组
grouped = df.groupby('category')

# 遍历分组
for name, group in grouped:
    print(f"Group: {name}")
    print(group)
    print()

Output:

Pandas GroupBy 分组操作及获取分组详解

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

4. 对分组进行聚合操作

GroupBy对象支持多种聚合操作,可以帮助我们快速计算各种统计指标:

4.1 使用内置聚合函数

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 按product列进行分组并计算多个统计指标
result = df.groupby('product')['sales'].agg(['mean', 'sum', 'count'])
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用内置聚合函数计算多个统计指标。

4.2 使用自定义聚合函数

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 自定义聚合函数
def custom_agg(x):
    return f"pandasdataframe.com_{x.max() - x.min()}"

# 按product列进行分组并应用自定义聚合函数
result = df.groupby('product')['sales'].agg(custom_agg)
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用自定义聚合函数。在这里,我们计算了每个产品的销售额范围。

4.3 对不同列应用不同的聚合函数

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'quantity': [10, 15, 12, 20, 18, 14]
}
df = pd.DataFrame(data)

# 对不同列应用不同的聚合函数
result = df.groupby('product').agg({
    'sales': 'sum',
    'quantity': 'mean'
})
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何对不同的列应用不同的聚合函数。

5. 分组转换操作

除了聚合操作,GroupBy还支持转换操作,可以对每个分组内的数据进行变换:

5.1 使用内置转换函数

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 计算每个产品的销售额占该产品总销售额的百分比
result = df.groupby('product')['sales'].transform(lambda x: x / x.sum() * 100)
df['sales_percentage'] = result
print(df)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用transform方法计算每个产品的销售额占比。

5.2 使用自定义转换函数

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 自定义转换函数
def custom_transform(x):
    return f"pandasdataframe.com_{x - x.mean():.2f}"

# 应用自定义转换函数
result = df.groupby('product')['sales'].transform(custom_transform)
df['sales_diff'] = result
print(df)

这个例子展示了如何使用自定义转换函数。在这里,我们计算了每个销售额与该产品平均销售额的差值。

6. 分组过滤操作

GroupBy还支持过滤操作,可以根据某些条件筛选出特定的分组:

6.1 使用filter方法

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 筛选出总销售额大于500的产品
result = df.groupby('product').filter(lambda x: x['sales'].sum() > 500)
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用filter方法筛选出总销售额大于500的产品。

6.2 使用apply方法进行复杂过滤

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': ['2023-01-01', '2023-01-02', '2023-01-01', '2023-01-03', '2023-01-02', '2023-01-03']
}
df = pd.DataFrame(data)

# 筛选出每个日期销售额最高的产品
def top_product(group):
    return group.loc[group['sales'].idxmax()]

result = df.groupby('date').apply(top_product)
print(result)

这个例子展示了如何使用apply方法进行复杂的过滤操作,筛选出每个日期销售额最高的产品。

7. 分组排序操作

GroupBy还支持排序操作,可以对分组内的数据进行排序:

7.1 使用sort_values方法

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': ['2023-01-01', '2023-01-02', '2023-01-01', '2023-01-03', '2023-01-02', '2023-01-03']
}
df = pd.DataFrame(data)

# 对每个产品的销售额进行降序排序
result = df.sort_values(['product', 'sales'], ascending=[True, False])
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用sort_values方法对每个产品的销售额进行降序排序。

7.2 使用nlargest方法

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 获取每个产品销售额最高的两条记录
result = df.groupby('product').apply(lambda x: x.nlargest(2, 'sales'))
print(result)

这个例子展示了如何使用nlargest方法获取每个产品销售额最高的两条记录。

8. 分组计算累计和滚动统计量

GroupBy还支持计算累计和滚动统计量,这在时间序列分析中特别有用:

8.1 计算累计和

8.1 计算累计和

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05', '2023-01-06']
}
df = pd.DataFrame(data)

# 计算每个产品的累计销售额
df['cumulative_sales'] = df.groupby('product')['sales'].cumsum()
print(df)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何计算每个产品的累计销售额。cumsum()方法用于计算累计和。

8.2 计算滚动平均

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': pd.date_range(start='2023-01-01', periods=6, freq='D')
}
df = pd.DataFrame(data)

# 计算每个产品的3天滚动平均销售额
df['rolling_avg'] = df.groupby('product')['sales'].rolling(window=3, min_periods=1).mean().reset_index(level=0, drop=True)
print(df)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何计算每个产品的3天滚动平均销售额。rolling()方法用于创建滚动窗口,mean()方法用于计算平均值。

9. 分组操作的高级技巧

以下是一些使用GroupBy进行数据分析的高级技巧:

9.1 使用多级索引

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'category': ['X', 'Y', 'X', 'Z', 'Y', 'Z'],
    'sales': [100, 200, 150, 300, 250, 180],
    'date': pd.date_range(start='2023-01-01', periods=6, freq='D')
}
df = pd.DataFrame(data)

# 使用多级索引进行分组
result = df.groupby(['product', 'category'])['sales'].sum().unstack()
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用多级索引进行分组,并使用unstack()方法将结果转换为更易读的形式。

9.2 使用agg方法同时计算多个统计量

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180],
    'quantity': [10, 15, 12, 20, 18, 14]
}
df = pd.DataFrame(data)

# 同时计算多个统计量
result = df.groupby('product').agg({
    'sales': ['sum', 'mean', 'max'],
    'quantity': ['sum', 'mean', 'min']
})
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用agg方法同时计算多个统计量,包括销售额的总和、平均值和最大值,以及数量的总和、平均值和最小值。

9.3 使用transform方法进行组内标准化

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 进行组内标准化
df['sales_normalized'] = df.groupby('product')['sales'].transform(lambda x: (x - x.mean()) / x.std())
print(df)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用transform方法进行组内标准化,将每个产品的销售额转换为标准分数。

10. GroupBy的性能优化

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

10.1 使用categoricals

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'] * 1000,
    'sales': [100, 200, 150, 300, 250, 180] * 1000
}
df = pd.DataFrame(data)

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

# 进行分组操作
result = df.groupby('product')['sales'].sum()
print(result)

这个例子展示了如何将分组列转换为categorical类型,这可以显著提高GroupBy的性能,特别是在处理具有大量重复值的列时。

10.2 使用numba加速

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

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'] * 1000,
    'sales': np.random.randint(100, 1000, 6000)
}
df = pd.DataFrame(data)

@jit(nopython=True)
def custom_sum(values):
    return np.sum(values)

# 使用numba加速的自定义函数进行分组操作
result = df.groupby('product')['sales'].agg(custom_sum)
print(result)

这个例子展示了如何使用numba库来加速自定义聚合函数。numba可以将Python函数编译成机器代码,从而显著提高性能。

11. GroupBy的常见陷阱和注意事项

在使用GroupBy时,有一些常见的陷阱需要注意:

11.1 处理NaN值

import pandas as pd
import numpy as np

# 创建包含NaN值的示例数据
data = {
    'product': ['A', 'B', 'A', np.nan, 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 分组时处理NaN值
result = df.groupby('product', dropna=False)['sales'].sum()
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何在分组时处理NaN值。默认情况下,GroupBy会忽略NaN值,但我们可以通过设置dropna=False来包含它们。

11.2 注意分组列的数据类型

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': ['100', '200', '150', '300', '250', '180']
}
df = pd.DataFrame(data)

# 确保sales列为数值类型
df['sales'] = pd.to_numeric(df['sales'])

# 进行分组操作
result = df.groupby('product')['sales'].sum()
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了在进行数值计算之前,确保相关列的数据类型正确的重要性。在这里,我们使用pd.to_numeric()函数将sales列转换为数值类型。

12. 结合其他Pandas功能使用GroupBy

GroupBy可以与其他Pandas功能结合使用,以进行更复杂的数据分析:

12.1 结合merge使用

import pandas as pd

# 创建销售数据
sales_data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'sales': [100, 200, 150, 300, 250, 180]
}
sales_df = pd.DataFrame(sales_data)

# 创建产品信息数据
product_info = {
    'product': ['A', 'B', 'C'],
    'category': ['X', 'Y', 'Z']
}
product_df = pd.DataFrame(product_info)

# 合并数据并进行分组操作
merged_df = pd.merge(sales_df, product_df, on='product')
result = merged_df.groupby('category')['sales'].sum()
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何结合merge和GroupBy功能,先合并销售数据和产品信息,然后按产品类别进行分组和汇总。

12.2 结合pivot_table使用

import pandas as pd

# 创建示例数据
data = {
    'product': ['A', 'B', 'A', 'C', 'B', 'A'],
    'category': ['X', 'Y', 'X', 'Z', 'Y', 'Z'],
    'sales': [100, 200, 150, 300, 250, 180]
}
df = pd.DataFrame(data)

# 使用pivot_table进行分组和汇总
result = pd.pivot_table(df, values='sales', index='product', columns='category', aggfunc='sum', fill_value=0)
print(result)

Output:

Pandas GroupBy 分组操作及获取分组详解

这个例子展示了如何使用pivot_table函数,它结合了GroupBy的功能,可以更灵活地创建交叉表。

总结

Pandas的GroupBy功能是进行数据分析的强大工具。通过本文的详细介绍,我们了解了如何创建GroupBy对象、获取分组信息、进行聚合操作、转换操作、过滤操作、排序操作以及计算累计和滚动统计量。我们还探讨了一些高级技巧、性能优化方法和常见陷阱。

掌握这些技能将使你能够更有效地处理和分析复杂的数据集。记住,实践是提高数据分析技能的关键。尝试将这些概念应用到你自己的数据集中,你会发现GroupBy是一个非常灵活和强大的工具。

最后,始终牢记数据的质量和完整性。在进行任何分析之前,确保你理解你的数据,并进行必要的清理和预处理。只有这样,你才能从GroupBy操作中获得最有价值的洞察。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程