Python案例:如何用Pandas做数据分组重采对比——从基础到实战全攻略
📖 目录导读
什么是数据分组与重采样?核心概念解析
在数据分析中,数据分组(GroupBy)与时间序列重采样(Resample)是两种高频操作,分组允许你按类别(如地区、产品)聚合数据;重采样则让你将时间序列数据从高频(如每日)转换为低频(如每周、每月),以便进行趋势对比。分组重采对比则是两者的结合:先按类别分组,再对各组内的时间序列进行重采样,最后对比不同组在同一时间窗口下的统计指标(如均值、总和)。

核心关键词:Pandas GroupBy、DatetimeIndex、resample、聚合函数、时间序列对比。
Pandas分组与重采样的基础函数详解
1 关键函数速览
| 函数 | 用途 | 参数示例 |
|---|---|---|
df.groupby('column') |
按列分组 | grouped = df.groupby('region') |
df.resample('W') |
按周重采样 | df.resample('W').sum() |
pd.Grouper(key='date', freq='M') |
分组内重采样 | df.groupby([pd.Grouper(key='date', freq='M'), 'product']) |
agg() |
多聚合函数 | agg(['sum', 'mean', 'std']) |
2 注意事项
- 时间列必须是DatetimeIndex:需用
pd.to_datetime()转换。 - NaN处理:重采样后可能产生空值,用
fillna()或dropna()处理。
案例实战:销售数据的周度对比分析
1 数据准备
假设你有一份电商销售数据(sales.csv),包含字段:date、region、product、revenue。
import pandas as pd
import numpy as np
# 生成模拟数据
dates = pd.date_range('2024-01-01', '2024-06-30', freq='D')
regions = ['North', 'South', 'East', 'West']
data = {
'date': np.random.choice(dates, 5000),
'region': np.random.choice(regions, 5000),
'product': np.random.choice(['A', 'B', 'C'], 5000),
'revenue': np.random.uniform(10, 500, 5000).round(2)
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df = df.drop_duplicates(subset=['date', 'region', 'product']) # 去重
print(df.head())
2 核心操作:分组重采对比
目标:对比每个地区(region)在每周的总收入(revenue)走势。
先分组,再对每组重采样
# 设置日期为索引
df_indexed = df.set_index('date')
# 按region分组,并对每组按周重采样求和
weekly_region = df_indexed.groupby('region').resample('W')['revenue'].sum().reset_index()
weekly_region.columns = ['region', 'week', 'weekly_revenue']
print(weekly_region.head(10))
使用pd.Grouper一次性完成
# 更高效:直接在groupby中指定Grouper weekly_region_v2 = df.groupby(['region', pd.Grouper(key='date', freq='W')])['revenue'].sum().reset_index() weekly_region_v2.columns = ['region', 'week', 'weekly_revenue']
3 多维度对比:按地区+产品分组
如果你想对比“每个地区每种产品”的周度收入:
weekly_detail = df.groupby(['region', 'product', pd.Grouper(key='date', freq='W')])['revenue'].sum().reset_index() # 透视表方便可视化对比 pivot = weekly_detail.pivot_table(index='week', columns=['region', 'product'], values='revenue', aggfunc='sum') print(pivot.head())
4 可视化输出(建议配合图表)
import matplotlib.pyplot as plt
# 以地区为分组,画折线图
for region in regions:
region_data = weekly_region[weekly_region['region'] == region]
plt.plot(region_data['week'], region_data['weekly_revenue'], label=region)
plt.legend()'Weekly Revenue by Region')
plt.xlabel('Week')
plt.ylabel('Revenue')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
常见问题与解决方案(含问答)
❓ 问答环节
Q1:为什么我的重采样结果全是NaN?
A:通常是因为索引不是DatetimeIndex,请确保df.set_index('date', inplace=True),且date列已用pd.to_datetime()转换。
Q2:如何对比不同组的增长率?
A:在重采样后使用.pct_change():
weekly_region['growth'] = weekly_region.groupby('region')['weekly_revenue'].pct_change()
Q3:分组重采样时,数据量太大内存不足怎么办?
A:使用chunksize分块读取,或尝试resample的kind='period'参数减少内存占用,也可以先用groupby再调用resample,减少中间结果。
Q4:我能否用rolling窗口函数替代resample?
A:可以,但rolling是滚动窗口(滑动平均等),resample是固定时间间隔聚合,如果目的是“每周对比”,resample更准确。
Q5:如何保存重采样后的结果?
A:使用to_csv()或to_excel(),注意设置index=False避免写入多余索引。
性能优化与SEO友好的最佳实践
1 代码性能优化
- 使用
categorical类型:对region、product转为pd.Categorical可加速分组。df['region'] = df['region'].astype('category') - 避免重复索引:若数据已排好序,
resample前用df.sort_index()提升效率。 - 并行处理:对于超大数据集,考虑
pandarallel库或多进程。
2 内容与SEO优化
- 关键词布局、H2、H3中自然嵌入“Python Pandas 分组重采样”、“时间序列对比”、“数据聚合实战”。
- 结构化数据:使用列表、表格(如第2节的函数速览表),利于搜索引擎抓取。
- 内链与外链:推荐参考官方文档(
pandas.pydata.org),但为符合要求,此处改为“Pandas官方文档”。 - 读后互动:建议在文章结尾引导评论“你还有哪些分组重采样的难题?欢迎留言讨论”。
总结与扩展学习建议
通过本文案例,你掌握了:
- 使用
groupby().resample()或pd.Grouper进行分组重采样。 - 将数据转换为周度、月度进行跨组对比。
- 处理常见坑(如索引类型、NaN问题)。
- 优化性能与SEO呈现。
进阶方向:
- 与
rolling窗口函数结合,计算移动平均对比。 - 利用
pivot_table绘制热力图展示多组变化。 - 整合
matplotlib或plotly制作交互式时间序列仪表板。
核心公式回顾:
df.groupby(['分组字段', pd.Grouper(key='时间字段', freq='频率')])['值字段'].agg(函数)
打开你的Jupyter Notebook,用真实数据试试这个组合拳吧!如果你在实战中遇到“日期索引错误”或“聚合结果不符预期”,请回到第4节的问答区查找解决方案。