本文目录导读:

- 目录导读
- 为什么分组重采样是数据分析的核心能力
- 技术基础:Pandas分组与重采样的核心函数
- 案例一:销售数据按周分组重采样,兼容不同时间粒度
- 案例二:多列分组+重采样,处理不规则频率数据
- 案例三:分组重采样后的缺失值填充,保证数据兼容
- 常见错误与避坑指南
- 问答环节:解决你的实际困惑
- 总结与进阶建议
Python案例实战:如何用Pandas进行数据分组与重采样,实现兼容性分析
目录导读
- 引言:为什么分组重采样是数据分析的核心能力
- 技术基础:Pandas分组与重采样的核心函数
- 销售数据按周分组重采样,兼容不同时间粒度
- 多列分组+重采样,处理不规则频率数据
- 分组重采样后的缺失值填充,保证数据兼容
- 常见错误与避坑指南
- 问答环节:解决你的实际困惑
- 总结与进阶建议
为什么分组重采样是数据分析的核心能力
在数据分析工作中,我们经常遇到这样的场景:业务数据以“每秒”或“每分钟”采集,但业务汇报需要“每日”或“每周”的汇总,更复杂的是,数据可能来自不同地区、不同产品线,需要先按类别分组,然后在每个组内进行时间重采样。
这就是分组+重采样的实战价值,Pandas的groupby()和resample()函数组合,能够让你:
- 将高频数据降采样为低频(如秒→天)
- 将低频数据升采样为高频(如月→日,需填充)
- 在不同时间粒度之间无损转换
据Google搜索趋势显示,“pandas groupby resample”相关查询在过去三年增长超过120%,说明这是数据分析师最频繁使用的技能之一。
Bing SEO提示:本篇文章提供直接可运行的Python代码案例,并解释每个参数的作用,确保你在搜索引擎中能找到最实操的解决方案。
技术基础:Pandas分组与重采样的核心函数
1 核心函数速览
# 基本语法
df.groupby('category').resample('W').sum()
df.groupby('category')['value'].resample('M').mean()
2 关键参数说明
groupby:指定分组列(可多列列表)resample:时间重采样,常用频率代码:'D': 日'W': 周(默认周日结束)'M': 月最后一天'Q': 季度'Y': 年
- 聚合函数:
sum(),mean(),std(),count(),last(),ohlc()
3 一个最小化示例
import pandas as pd
import numpy as np
# 创建示例数据
dates = pd.date_range('2024-01-01', periods=100, freq='H')
data = {
'类别': np.random.choice(['A', 'B', 'C'], 100),
'数值': np.random.randn(100)*10 + 50
}
df = pd.DataFrame({'时间': dates, **data})
df = df.set_index('时间')
# 按类别分组,按天重采样,计算平均值
result = df.groupby('类别').resample('D').mean()
print(result.head(10))
案例一:销售数据按周分组重采样,兼容不同时间粒度
1 问题描述
某电商平台有每分钟的订单量数据,包含产品线(A/B/C),需要输出:
- 每个产品线的周度总销量
- 同时兼容跨周的数据(比如周一开始的周)
2 完整代码实现
import pandas as pd
import numpy as np
# 生成模拟数据
np.random.seed(42)
date_rng = pd.date_range('2024-01-01 00:00', '2024-03-31 23:00', freq='min')
data = {
'product': np.random.choice(['A', 'B', 'C'], len(date_rng)),
'sales': np.random.poisson(5, len(date_rng)) # 泊松分布模拟订单数
}
df = pd.DataFrame(data, index=date_rng)
df.index.name = 'timestamp'
# 方法1:按周一为起始的周重采样
result_week = df.groupby('product').resample('W-MON').sum()
print(result_week.head(12))
# 方法2:按自然周(周日结束)
result_week_sun = df.groupby('product').resample('W-SUN').sum()
print(result_week_sun.head(12))
3 兼容性技巧
- 使用
W-MON、W-SUN等自定义周起始天 - 使用
offset参数:resample('W', loffset='-1D')让周数据对齐业务周期 - 对于跨国数据,可使用
W-THU(周四起始)适配某些国家的财年
案例二:多列分组+重采样,处理不规则频率数据
1 问题描述
原始数据有“地区”、“门店”、“品类”三个维度,且时间戳是不规则的(如某些天无数据),需要:
- 按(地区, 品类)分组
- 重采样为每日数据
- 兼容缺失的日期
2 实现方案
# 创建不规则时间数据
idx = pd.DatetimeIndex(['2024-01-01', '2024-01-03', '2024-01-10',
'2024-01-02', '2024-01-05', '2024-01-12'])
df_irreg = pd.DataFrame({
'region': ['east', 'east', 'east', 'west', 'west', 'west'],
'category': ['food', 'food', 'food', 'drink', 'drink', 'drink'],
'revenue': [100, 150, 200, 80, 120, 180]
}, index=idx)
df_irreg.index.name = 'date'
# 多列分组+重采样
result_multi = (df_irreg.groupby(['region', 'category'])
.resample('D')
.asfreq() # 直接填充NaN,显示频率
.fillna(0)) # 将NaN填充为0
# 或者使用 .ffill() 向前填充
result_multi_ffill = (df_irreg.groupby(['region', 'category'])
.resample('D')
.ffill())
print(result_multi.head(10))
3 关键理解
asfreq():强制显示所有时间点,缺失值用NaNfillna(0):对分组后的每个组独立填充,不会跨组.apply(lambda x: x.resample('D').pad()):更灵活的向前填充
案例三:分组重采样后的缺失值填充,保证数据兼容
1 问题场景
IoT传感器数据,每10分钟采集一次温度,但偶尔有丢包(缺失行),需要:
- 按传感器ID分组
- 重采样为每小时数据
- 对缺失的小时进行插值(线性或时间加权)
2 插值方法对比
# 模拟传感器数据
dates = pd.date_range('2024-06-01', periods=200, freq='10min')
# 故意删除一些点
missing_mask = np.random.rand(200) < 0.3
dates_clean = dates[~missing_mask]
sensor_data = pd.DataFrame({
'sensor_id': np.random.choice(['S1', 'S2', 'S3'], len(dates_clean)),
'temp': np.random.normal(22, 3, len(dates_clean))
}, index=dates_clean)
sensor_data.index.name = 'time'
# 分组+重采样到小时,并用不同方法填充
def resample_with_fill(group, method='linear'):
resampled = group.resample('H').asfreq()
if method == 'linear':
return resampled.interpolate(method='linear')
elif method == 'time':
return resampled.interpolate(method='time')
elif method == 'ffill':
return resampled.fillna(method='ffill')
# 应用线性插值
sensor_filled = (sensor_data.groupby('sensor_id')
.apply(lambda g: resample_with_fill(g, 'linear')))
print(sensor_filled.head(15))
3 兼容性最佳实践
- 线性插值:适合温度、压力等连续物理量
- 向前填充:适合状态量(如开关状态)
- 时间加权插值:
method='time'处理不规则时间间隔
常见错误与避坑指南
1 错误1:索引未设为时间类型
# 错误写法
df.groupby('col').resample('D').sum() # 报错
# 正确做法
df.set_index('date_col').groupby('col').resample('D').sum()
2 错误2:重采样后索引层级混乱
# 默认返回MultiIndex,可通过reset_index恢复
result = df.groupby('col').resample('D').sum().reset_index()
3 错误3:性能问题
- 大数据集可使用
pd.Grouper:df.groupby(pd.Grouper(freq='M'))替代set_index+resample - 使用
numba加速聚合(需先groupby().resample()组合)
问答环节:解决你的实际困惑
Q1: 为什么我的resample结果少了数据?
A: 检查时间索引是否完整,使用
asfreq()查看缺失时间点,或者用min(),max()检查时间范围。
Q2: 分组重采样后,如何保持原始数据行数?
A: 如果不想降采样,用
resample().transform():df.groupby('col')['value'].transform(lambda x: x.resample('D').sum())
Q3: 如何处理跨时区数据?
A: 先统一使用
tz_convert()转换时区,再重采样。df.index = df.index.tz_convert('UTC') df.groupby('col').resample('D').mean()
Q4: 有没有更快的分组重采样方法?
A: 大数据集建议使用
pandas的pivot_table+resample组合:先pivot再重采样,或使用dask并行计算。
总结与进阶建议
通过以上三个真实案例,你已掌握:
- 基础的分组+重采样语法
- 多列分组与不规则时间处理
- 缺失值填充与兼容性保证
- 常见避坑技巧
进阶学习路径:
- 探索
ohlc()金融数据重采样 - 学习
pd.Grouper进行窗口重置 - 结合
matplotlib可视化分组重采样结果 - 研究
xarray处理多维时间序列
SEO优化建议:如果你的文章出现在Bing或Google第一页,请确保代码可直接复制运行,且包含丰富的pandas和resample语义相关词(如“pandas rolling mean”、“python time series aggregation”等)。