Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

参考:pandas groupby aggregate multiple columns

Pandas是Python中强大的数据处理库,其中groupby和aggregate功能为处理大型数据集提供了高效的分组和聚合操作。本文将详细介绍如何在Pandas中使用groupby和aggregate对多列数据进行分组聚合,包括基本概念、常用方法、高级技巧以及实际应用场景。

1. Pandas groupby和aggregate的基本概念

在开始深入探讨之前,我们先来了解一下groupby和aggregate的基本概念。

1.1 groupby简介

groupby是Pandas中用于数据分组的方法。它允许我们按照一个或多个列的值将数据分成不同的组,然后对每个组进行操作。groupby的基本语法如下:

import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
    'age': [25, 30, 35, 25, 31],
    'city': ['New York', 'London', 'Paris', 'New York', 'London'],
    'salary': [50000, 60000, 70000, 55000, 65000]
})

grouped = df.groupby('name')

在这个例子中,我们创建了一个简单的DataFrame,然后按照’name’列进行分组。

1.2 aggregate简介

aggregate(通常简写为agg)是用于对分组后的数据进行聚合操作的方法。它可以应用一个或多个聚合函数到指定的列上。基本语法如下:

result = grouped.agg({'age': 'mean', 'salary': 'sum'})

这个例子展示了如何对分组后的数据计算年龄的平均值和薪水的总和。

2. 使用groupby对单列进行分组

让我们从最简单的情况开始,对单列进行分组并进行聚合操作。

import pandas as pd

df = pd.DataFrame({
    'category': ['A', 'B', 'A', 'B', 'A', 'C'],
    'value': [10, 20, 15, 25, 30, 35],
    'website': ['pandasdataframe.com'] * 6
})

result = df.groupby('category')['value'].sum()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

在这个例子中,我们按’category’列进行分组,然后计算每个类别的’value’列总和。这是最基本的groupby操作,适用于简单的数据分析任务。

3. 对多列进行分组

在实际应用中,我们经常需要按多个列进行分组。Pandas允许我们轻松地实现这一点。

import pandas as pd

df = pd.DataFrame({
    'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
    'category': ['A', 'B', 'A', 'B'],
    'value': [100, 200, 150, 250],
    'website': ['pandasdataframe.com'] * 4
})

result = df.groupby(['date', 'category'])['value'].sum()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何按’date’和’category’两列进行分组,然后计算每个组合的’value’总和。这种方法在时间序列数据分析中特别有用。

4. 使用aggregate对多列进行聚合

aggregate方法允许我们对多个列应用不同的聚合函数。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value1': [10, 20, 30, 40, 50],
    'value2': [100, 200, 300, 400, 500],
    'website': ['pandasdataframe.com'] * 5
})

result = df.groupby('group').agg({
    'value1': 'mean',
    'value2': ['sum', 'max']
})
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

在这个例子中,我们对’value1’列计算平均值,对’value2’列同时计算总和和最大值。这种方法可以在一次操作中获得多种统计结果。

5. 使用自定义函数进行聚合

除了内置的聚合函数,Pandas还允许我们使用自定义函数进行聚合操作。

import pandas as pd

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

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

result = df.groupby('group')['value'].agg([custom_agg, 'mean'])
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何定义一个自定义函数(计算最大值和最小值的差),并将其与内置函数一起用于聚合操作。

6. 对不同列应用不同的聚合函数

在某些情况下,我们可能需要对不同的列应用不同的聚合函数。Pandas提供了灵活的方式来实现这一点。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value1': [10, 20, 30, 40, 50],
    'value2': [100, 200, 300, 400, 500],
    'value3': [1, 2, 3, 4, 5],
    'website': ['pandasdataframe.com'] * 5
})

result = df.groupby('group').agg({
    'value1': 'sum',
    'value2': 'mean',
    'value3': ['min', 'max']
})
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何对’value1’列求和,对’value2’列计算平均值,对’value3’列同时计算最小值和最大值。

7. 使用lambda函数进行聚合

lambda函数提供了一种简洁的方式来定义简单的聚合操作。

import pandas as pd

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

result = df.groupby('group')['value'].agg([
    ('sum', 'sum'),
    ('mean', 'mean'),
    ('range', lambda x: x.max() - x.min())
])
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

在这个例子中,我们使用lambda函数计算了每个组的值范围(最大值减最小值)。

8. 对多个列应用相同的聚合函数

有时我们需要对多个列应用相同的聚合函数。Pandas提供了简便的方法来实现这一点。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value1': [10, 20, 30, 40, 50],
    'value2': [100, 200, 300, 400, 500],
    'value3': [1, 2, 3, 4, 5],
    'website': ['pandasdataframe.com'] * 5
})

result = df.groupby('group').agg(['mean', 'sum'])
print(result)

这个例子展示了如何对所有数值列同时计算平均值和总和。

9. 使用named aggregation

Pandas 0.25.0版本引入了named aggregation,这提供了一种更清晰、更易读的方式来定义聚合操作。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value1': [10, 20, 30, 40, 50],
    'value2': [100, 200, 300, 400, 500],
    'website': ['pandasdataframe.com'] * 5
})

result = df.groupby('group').agg(
    value1_mean=('value1', 'mean'),
    value1_sum=('value1', 'sum'),
    value2_max=('value2', 'max')
)
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子使用named aggregation计算’value1’的平均值和总和,以及’value2’的最大值。结果列名更加清晰明了。

10. 使用groupby和transform

transform方法允许我们在保持原始DataFrame形状的同时进行分组计算。

import pandas as pd

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

df['group_mean'] = df.groupby('group')['value'].transform('mean')

这个例子计算了每个组的平均值,并将结果添加为新的列,保持了原始DataFrame的形状。

11. 处理缺失值

在进行分组聚合时,处理缺失值是一个常见的问题。Pandas提供了多种方法来处理这种情况。

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value': [10, np.nan, 30, 40, np.nan],
    'website': ['pandasdataframe.com'] * 5
})

result = df.groupby('group')['value'].agg(['mean', 'count', 'size'])
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何计算每个组的平均值(忽略NaN),非NaN值的数量(count),以及组中的总元素数(size)。

12. 使用groupby和apply

apply方法允许我们对每个组应用更复杂的操作。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C'],
    'value1': [10, 20, 30, 40, 50],
    'value2': [100, 200, 300, 400, 500],
    'website': ['pandasdataframe.com'] * 5
})

def custom_func(group):
    return pd.Series({
        'value1_mean': group['value1'].mean(),
        'value2_sum': group['value2'].sum(),
        'combined': group['value1'].mean() + group['value2'].sum()
    })

result = df.groupby('group').apply(custom_func)
print(result)

这个例子展示了如何使用自定义函数对每个组进行复杂的计算。

13. 分组聚合后的排序

在进行分组聚合后,我们可能需要对结果进行排序。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [10, 20, 30, 40, 50, 60],
    'website': ['pandasdataframe.com'] * 6
})

result = df.groupby('group')['value'].sum().sort_values(ascending=False)
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何按组计算’value’的总和,然后按降序排列结果。

14. 使用多级索引

当使用多列进行分组时,结果通常会有多级索引。我们可以使用unstack方法来重塑结果。

import pandas as pd

df = pd.DataFrame({
    'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
    'category': ['A', 'B', 'A', 'B'],
    'value': [100, 200, 150, 250],
    'website': ['pandasdataframe.com'] * 4
})

result = df.groupby(['date', 'category'])['value'].sum().unstack()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何按’date’和’category’分组,计算’value’的总和,然后将结果重塑为一个更易读的表格形式。

15. 使用groupby和filter

filter方法允许我们基于组级别的条件来过滤数据。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [10, 20, 30, 40, 50, 60],
    'website': ['pandasdataframe.com'] * 6
})

result = df.groupby('group').filter(lambda x: x['value'].mean() > 35)
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何只保留那些’value’平均值大于35的组。

16. 使用groupby和cumulative函数

Pandas提供了一系列累积函数,可以在分组后应用。

import pandas as pd

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value': [10, 20, 30, 40, 50, 60],
    'website': ['pandasdataframe.com'] * 6
})

result = df.groupby('group')['value'].cumsum()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子计算了每个组内’value’的累积和。

17. 处理时间序列数据

在处理时间序列数据时,groupby和resample经常一起使用。

import pandas as pd

df = pd.DataFrame({
    'date': pd.date_range(start='2023-01-01', periods=6),
    'value': [10, 20, 30, 40, 50, 60],
    'website': ['pandasdataframe.com'] * 6
})

df.set_index('date', inplace=True)
result = df.groupby(pd.Grouper(freq='2D'))['value'].sum()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何将数据按2天为一组进行分组,并计算每组的’value’总和。这在处理日期数据时非常有用。

18. 使用groupby和agg进行复杂的聚合操作

有时我们需要在一个操作中执行多种复杂的聚合。Pandas的agg方法提供了强大的功能来实现这一点。

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'group': ['A', 'A', 'B', 'B', 'C', 'C'],
    'value1': [10, 20, 30, 40, 50, 60],
    'value2': [100, 200, 300, 400, 500, 600],
    'website': ['pandasdataframe.com'] * 6
})

result = df.groupby('group').agg({
    'value1': ['mean', 'std', lambda x: x.max() - x.min()],
    'value2': ['sum', 'median', lambda x: np.percentile(x, 75)]
})
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

在这个例子中,我们对’value1’列计算了平均值、标准差和范围(最大值减最小值),对’value2’列计算了总和、中位数和75百分位数。这种方法允许我们在一次操作中获得丰富的统计信息。

19. 使用groupby和pivot_table

pivot_table函数提供了另一种方式来进行分组聚合,特别是当我们需要处理多维数据时。

import pandas as pd

df = pd.DataFrame({
    'date': ['2023-01-01', '2023-01-01', '2023-01-02', '2023-01-02'],
    'category': ['A', 'B', 'A', 'B'],
    'value1': [100, 200, 150, 250],
    'value2': [10, 20, 15, 25],
    'website': ['pandasdataframe.com'] * 4
})

result = pd.pivot_table(df, values=['value1', 'value2'], index='date', 
                        columns='category', aggfunc={'value1': 'sum', 'value2': 'mean'})
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子使用pivot_table函数按’date’和’category’进行分组,对’value1’计算总和,对’value2’计算平均值。结果是一个多层次的表格,易于理解和分析。

20. 使用groupby和rolling窗口函数

rolling窗口函数可以与groupby结合使用,以计算移动平均等统计量。

import pandas as pd

df = pd.DataFrame({
    'date': pd.date_range(start='2023-01-01', periods=10),
    'group': ['A', 'B'] * 5,
    'value': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
    'website': ['pandasdataframe.com'] * 10
})

df.set_index('date', inplace=True)
result = df.groupby('group')['value'].rolling(window=3).mean()
print(result)

Output:

Pandas中使用groupby和aggregate对多列数据进行高效分组聚合

这个例子展示了如何按’group’分组,然后计算’value’的3天移动平均。这种方法在时间序列分析中非常有用,可以帮助识别趋势和模式。

总结

Pandas的groupby和aggregate功能为数据分析提供了强大而灵活的工具。通过本文介绍的各种方法和技巧,我们可以轻松地对复杂的数据集进行分组和聚合操作。从基本的单列分组到复杂的多列聚合,从内置函数到自定义函数,Pandas都提供了直观和高效的解决方案。

在实际应用中,我们可能需要根据具体的数据结构和分析需求,灵活地组合使用这些方法。例如,我们可能需要先使用groupby和aggregate进行初步的数据汇总,然后使用pivot_table重塑数据,最后应用rolling窗口函数进行时间序列分析。

此外,在处理大型数据集时,我们还需要考虑性能问题。某些操作可能会消耗大量内存或计算资源,因此在处理大数据时,可能需要考虑使用更高效的方法或采用分布式计算框架。

最后,随着Pandas的不断发展,新的功能和优化也在不断推出。保持对Pandas最新版本的关注,并经常查阅官方文档,可以帮助我们更好地利用这个强大的数据处理工具。

通过掌握本文介绍的这些技巧,我们可以更加高效地处理和分析各种复杂的数据集,从而为数据驱动的决策提供有力支持。无论是在商业分析、科学研究还是其他领域,这些技能都将大有用武之地。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程