别再死记硬背groupby了!用真实酒水消费数据5分钟掌握Pandas分组聚合

当你第一次面对一份包含全球酒水消费数据的CSV文件时,是否曾感到无从下手?作为数据分析师,我们每天都要处理这样的真实数据集。今天,我将带你用Pandas的groupby功能,像专业人士一样分析各大洲的饮酒偏好。

1. 从数据探索开始:理解你的战场

拿到drinks.csv文件后,不要急着写代码。优秀的数据分析师会先花时间了解数据全貌:

import pandas as pd
drinks = pd.read_csv('drinks.csv')
print(drinks.head())
print(drinks.info())
print(drinks.describe())

这三个简单的命令会告诉你:

  • 数据的前几行样本
  • 每列的数据类型和缺失值情况
  • 数值列的基本统计量(均值、标准差等)

提示:在Jupyter Notebook中,直接输入drinks.sample(5)可以随机查看5行数据,这比head()更能发现数据异常。

2. 分组聚合的核心思维:分割-应用-组合

Pandas的groupby遵循三个步骤:

  1. 分割:按指定键(如continent列)将数据分成若干组
  2. 应用:对每个组执行计算(求和、均值等)
  3. 组合:将结果合并为新的数据结构

让我们看一个最简单的例子——计算各大洲的平均啤酒消耗量:

beer_by_continent = drinks.groupby('continent')['beer_servings'].mean()
print(beer_by_continent.sort_values(ascending=False))

3. 进阶技巧:多维度分析与自定义聚合

3.1 同时分析多个指标

现实业务中,我们往往需要一次性计算多个统计量。agg()方法可以完美解决这个问题:

result = drinks.groupby('continent').agg({
    'beer_servings': ['sum', 'mean', 'max'],
    'wine_servings': lambda x: x.max() - x.min()  # 计算极差
})
print(result)

3.2 处理复杂业务逻辑

当内置函数无法满足需求时,可以定义自己的聚合函数。比如,我们想找出每个大洲酒精消费的"典型国家"(消费量最接近平均值):

def find_typical_country(series):
    avg = series.mean()
    return series.iloc[(series-avg).abs().argsort()[:1]].index[0]

typical_countries = drinks.groupby('continent').apply(
    lambda g: find_typical_country(g['total_litres_of_pure_alcohol'])
)
print(typical_countries)

4. 避坑指南:常见错误与解决方案

4.1 忘记重置索引

groupby操作后,分组键会变成索引。要恢复常规DataFrame结构,使用reset_index():

df = drinks.groupby('continent').size().reset_index(name='country_count')

4.2 处理缺失值

分组时遇到缺失值可能导致意外结果。建议先检查:

print(drinks.isnull().sum())

对于continent列的缺失,我们可以:

clean_drinks = drinks.dropna(subset=['continent'])  # 删除缺失
# 或者
drinks['continent'] = drinks['continent'].fillna('UNKNOWN')  # 填充默认值

4.3 性能优化技巧

当处理大数据集时,可以显著提升速度的方法:

# 方法1:只选择需要的列
cols = ['continent', 'beer_servings', 'wine_servings']
drinks[cols].groupby('continent').mean()

# 方法2:使用category类型优化
drinks['continent'] = drinks['continent'].astype('category')

5. 从分析到洞察:制作专业报告

最后,让我们将分析结果转化为业务人员能理解的报告:

report = drinks.groupby('continent').agg({
    'beer_servings': ['mean', 'std'],
    'wine_servings': ['mean', 'std'],
    'total_litres_of_pure_alcohol': 'median'
}).round(1)

# 重命名列
report.columns = ['_'.join(col).strip() for col in report.columns.values]
report = report.rename(columns={
    'beer_servings_mean': '平均啤酒消费量',
    'beer_servings_std': '啤酒消费标准差',
    'wine_servings_mean': '平均红酒消费量',
    'total_litres_of_pure_alcohol_median': '酒精消费中位数'
})

print(report.sort_values('平均啤酒消费量', ascending=False))

这个最终报告清晰地展示了:

  • 欧洲在啤酒和红酒消费上都位居榜首
  • 非洲的酒精消费差异最大(高标准差)
  • 南美洲的葡萄酒消费相对均衡
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐