Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

参考:pandas groupby then mean

在数据分析和处理中,我们经常需要对数据进行分组并计算统计量。Pandas 作为 Python 中强大的数据处理库,提供了 GroupBy 和 Mean 等功能,使得这些操作变得简单高效。本文将详细介绍 Pandas 中的 GroupBy 和 Mean 操作,包括它们的基本用法、高级技巧以及实际应用场景。

1. GroupBy 基础

GroupBy 是 Pandas 中用于数据分组的核心功能。它允许我们根据一个或多个列的值将数据分成不同的组,然后对每个组进行独立的操作。

1.1 基本语法

GroupBy 的基本语法如下:

import pandas as pd

# 创建示例数据
df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 按 Category 列分组
grouped = df.groupby('Category')

在这个例子中,我们创建了一个包含 Category、Value 和 Site 列的 DataFrame,然后使用 groupby() 方法按 Category 列进行分组。

1.2 查看分组结果

分组后,我们可以使用多种方法查看分组结果:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

grouped = df.groupby('Category')

# 查看分组的大小
print(grouped.size())

# 查看分组的组别
print(grouped.groups)

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

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个示例展示了如何查看分组的大小、组别以及如何遍历每个分组。

2. Mean 操作

Mean 是一种常用的统计操作,用于计算数值的平均值。在 Pandas 中,我们可以轻松地对整个 DataFrame 或特定列执行 Mean 操作。

2.1 基本用法

import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'Site': ['pandasdataframe.com'] * 5
})

# 计算整个 DataFrame 的平均值
print(df.mean())

# 计算特定列的平均值
print(df['A'].mean())

这个例子展示了如何计算整个 DataFrame 和特定列的平均值。

2.2 忽略非数值列

当 DataFrame 包含非数值列时,Mean 操作会自动忽略这些列:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'C': ['x', 'y', 'z', 'x', 'y'],
    'Site': ['pandasdataframe.com'] * 5
})

# 计算平均值,自动忽略非数值列
print(df.mean())

在这个例子中,Mean 操作会自动忽略非数值列 ‘C’ 和 ‘Site’。

3. GroupBy 和 Mean 结合使用

GroupBy 和 Mean 的结合使用是数据分析中的常见操作,它允许我们计算每个分组的平均值。

3.1 基本用法

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 按 Category 分组并计算 Value 的平均值
result = df.groupby('Category')['Value'].mean()
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何按 Category 分组并计算每个组的 Value 平均值。

3.2 多列分组

我们可以按多个列进行分组:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'SubCategory': ['X', 'X', 'Y', 'Y', 'X', 'Y'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 按 Category 和 SubCategory 分组并计算 Value 的平均值
result = df.groupby(['Category', 'SubCategory'])['Value'].mean()
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何按多个列(Category 和 SubCategory)进行分组,并计算每个组的 Value 平均值。

4. 高级 GroupBy 和 Mean 操作

4.1 聚合多个统计量

我们可以同时计算多个统计量:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value1': [1, 2, 3, 4, 5, 6],
    'Value2': [10, 20, 30, 40, 50, 60],
    'Site': ['pandasdataframe.com'] * 6
})

# 按 Category 分组并计算多个统计量
result = df.groupby('Category').agg({
    'Value1': ['mean', 'max'],
    'Value2': ['mean', 'min']
})
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何按 Category 分组,并同时计算 Value1 的平均值和最大值,以及 Value2 的平均值和最小值。

4.2 自定义聚合函数

我们可以使用自定义函数进行聚合:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 自定义函数:计算中位数和标准差
def custom_agg(x):
    return pd.Series({
        'median': x.median(),
        'std': x.std()
    })

# 按 Category 分组并应用自定义聚合函数
result = df.groupby('Category')['Value'].apply(custom_agg)
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何创建一个自定义聚合函数,计算中位数和标准差,并将其应用于分组后的数据。

4.3 处理缺失值

在进行 GroupBy 和 Mean 操作时,我们可能需要处理缺失值:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, np.nan, 4, 5, np.nan],
    'Site': ['pandasdataframe.com'] * 6
})

# 忽略缺失值计算平均值
result1 = df.groupby('Category')['Value'].mean()

# 包含缺失值计算平均值
result2 = df.groupby('Category')['Value'].mean(skipna=False)

print("Ignoring NaN:")
print(result1)
print("\nIncluding NaN:")
print(result2)

这个例子展示了如何在存在缺失值的情况下计算分组平均值,以及如何选择忽略或包含缺失值。

5. 实际应用场景

5.1 销售数据分析

假设我们有一个销售数据集,我们想分析不同产品类别的平均销售额:

import pandas as pd

sales_data = pd.DataFrame({
    'Product': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
    'Category': ['Electronics', 'Clothing', 'Food', 'Electronics', 'Clothing', 'Food', 'Electronics', 'Clothing', 'Food'],
    'Sales': [100, 150, 50, 200, 100, 75, 150, 200, 60],
    'Site': ['pandasdataframe.com'] * 9
})

# 按产品类别计算平均销售额
avg_sales_by_category = sales_data.groupby('Category')['Sales'].mean()
print(avg_sales_by_category)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何分析不同产品类别的平均销售额。

5.2 学生成绩分析

假设我们有一个学生成绩数据集,我们想分析不同班级的平均分数:

import pandas as pd

student_data = pd.DataFrame({
    'Student': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'],
    'Class': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Math': [85, 92, 78, 95, 88, 90],
    'Science': [90, 85, 92, 88, 95, 87],
    'Site': ['pandasdataframe.com'] * 6
})

# 计算每个班级的平均分数
avg_scores_by_class = student_data.groupby('Class')[['Math', 'Science']].mean()
print(avg_scores_by_class)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何分析不同班级的平均数学和科学分数。

5.3 时间序列数据分析

对于时间序列数据,我们可能想要按时间间隔进行分组和平均:

import pandas as pd
import numpy as np

# 创建示例时间序列数据
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
values = np.random.randn(len(dates))
ts_data = pd.DataFrame({'Date': dates, 'Value': values, 'Site': ['pandasdataframe.com'] * len(dates)})

# 按月分组并计算平均值
monthly_avg = ts_data.groupby(ts_data['Date'].dt.to_period('M'))['Value'].mean()
print(monthly_avg)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何对时间序列数据按月分组并计算平均值。

6. 性能优化技巧

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

6.1 使用 categoricals

对于具有有限且重复值的列,将其转换为 categorical 类型可以提高性能:

import pandas as pd
import numpy as np

# 创建大型数据集
n = 1000000
df = pd.DataFrame({
    'Category': np.random.choice(['A', 'B', 'C'], n),
    'Value': np.random.randn(n),
    'Site': ['pandasdataframe.com'] * n
})

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

# 执行 GroupBy 和 Mean 操作
result = df.groupby('Category')['Value'].mean()
print(result)

这个例子展示了如何将分组列转换为 categorical 类型以提高性能。

6.2 使用 numba 加速

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

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

@jit(nopython=True)
def fast_mean(values):
    return values.mean()

df = pd.DataFrame({
    'Category': np.random.choice(['A', 'B', 'C'], 1000000),
    'Value': np.random.randn(1000000),
    'Site': ['pandasdataframe.com'] * 1000000
})

result = df.groupby('Category')['Value'].agg(fast_mean)
print(result)

这个例子展示了如何使用 numba 加速自定义聚合函数。

7. 常见问题和解决方案

7.1 处理多层索引结果

GroupBy 操作后的结果可能会有多层索引,我们可以使用 reset_index() 将其转换为普通 DataFrame:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'SubCategory': ['X', 'X', 'Y', 'Y', 'X', 'Y'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

result = df.groupby(['Category', 'SubCategory'])['Value'].mean().reset_index()
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何处理多层索引的 GroupBy 结果。

7.2 处理组内的空值

有时我们可能想要在计算平均值之前填充组内的空值:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, np.nan, 3, np.nan, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 先填充组内的空值,然后计算平均值
result = df.groupby('Category')['Value'].apply(lambda x: x.fillna(x.mean())).mean()
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何在计算分组平均值之前,先填充组内的空值。

7.3 处理不同数据类型的列

当 DataFrame 包含不同数据类型的列时,我们可能需要分别处理:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'NumericValue': [1, 2, 3, 4, 5, 6],
    'StringValue': ['x', 'y', 'z', 'x', 'y', 'z'],
    'Site': ['pandasdataframe.com'] * 6
})

# 对数值列计算平均值,对字符串列连接
result = df.groupby('Category').agg({
    'NumericValue': 'mean',
    'StringValue': lambda x: ','.join(set(x))
})
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何在 GroupBy 操作中同时处理数值列和字符串列。

8. 高级应用

8.1 滚动平均

除了简单的分组平均,我们还可以计算滚动平均:

import pandas as pd
import numpy as np

# 创建时间序列数据
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
df = pd.DataFrame({
    'Date': dates,
    'Value': np.random.randn(len(dates)),
    'Site': ['pandasdataframe.com'] * len(dates)
})

# 计算7天滚动平均
df['RollingMean'] = df['Value'].rolling(window=7).mean()

print(df.head(10))

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何计算时间序列数据的滚动平均。

8.2 分组后的排序

有时我们可能想要在分组后对每个组内的数据进行排序:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [3, 2, 1, 5, 4, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 按 Category 分组,然后在每个组内按 Value 排序
result = df.groupby('Category').apply(lambda x: x.sort_values('Value'))
print(result)

这个例子展示了如何在分组后对每个组内的数据进行排序。

8.3 分组后的过滤

我们可能想要基于某些条件过滤分组后的结果:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 只保留平均值大于3的组
result = df.groupby('Category').filter(lambda x: x['Value'].mean() > 3)
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何过滤掉不满足特定条件的组。

9. 与其他 Pandas 功能的结合

9.1 与 pivot_table 结合

GroupBy 和 Mean 操作可以与 pivot_table 结合使用,创建更复杂的数据视图:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'SubCategory': ['X', 'X', 'Y', 'Y', 'X', 'Y'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

pivot_result = pd.pivot_table(df, values='Value', index='Category', columns='SubCategory', aggfunc='mean')
print(pivot_result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何使用 pivot_table 创建一个交叉表,显示不同 Category 和 SubCategory 的平均 Value。

9.2 与 merge 结合

我们可以将 GroupBy 和 Mean 的结果与原始数据合并:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

# 计算每个 Category 的平均值
category_means = df.groupby('Category')['Value'].mean().reset_index(name='MeanValue')

# 将平均值合并回原始数据
result = pd.merge(df, category_means, on='Category')
print(result)

Output:

Pandas GroupBy 和 Mean 操作:数据分组与均值计算详解

这个例子展示了如何将分组计算的结果合并回原始数据。

9.3 与 apply 结合

我们可以使用 apply 方法在分组后应用更复杂的函数:

import pandas as pd

df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [1, 2, 3, 4, 5, 6],
    'Site': ['pandasdataframe.com'] * 6
})

def custom_function(group):
    return pd.Series({
        'Mean': group['Value'].mean(),
        'Max': group['Value'].max(),
        'Range': group['Value'].max() - group['Value'].min()
    })

result = df.groupby('Category').apply(custom_function)
print(result)

这个例子展示了如何使用 apply 方法在每个组上应用自定义函数。

10. 总结

Pandas 的 GroupBy 和 Mean 操作是数据分析中非常强大和灵活的工具。它们允许我们轻松地对数据进行分组、聚合和统计分析。通过本文的详细介绍和丰富的示例,我们了解了这些操作的基本用法、高级技巧以及实际应用场景。

从简单的分组平均计算到复杂的多维数据分析,GroupBy 和 Mean 操作几乎可以满足所有的数据聚合需求。它们不仅可以单独使用,还可以与 Pandas 的其他功能(如 pivot_table、merge 和 apply)结合,创建更复杂和信息丰富的数据视图。

在实际应用中,我们需要注意数据的质量和特性,合理处理缺失值和异常值,并根据具体需求选择适当的聚合方法。同时,对于大型数据集,我们还需要考虑性能优化,如使用 categoricals 或 numba 加速计算。

通过掌握这些技能,我们可以更有效地处理和分析各种类型的数据,从而为决策提供有力的支持。无论是在商业分析、科学研究还是其他领域,Pandas 的 GroupBy 和 Mean 操作都是不可或缺的工具。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程