重采样前须将时间列转为DatetimeIndex并设为索引,检查df.index.dtype为datetime64[ns];rule参数指定周期(如'D'日、'W-MON'周一周期、'ME'月末),链式调用聚合函数;补零用.asfreq(fill_value=0),高频降频慎用min_count防误判。

重采样前必须确保索引是DatetimeIndex
直接对DataFrame调用resample()会报TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex,因为pandas要求时间维度必须是明确的时间索引。常见错误是把时间列留在DataFrame里当普通列,或者用了字符串类型的时间列。
实操建议:
- 用
df.set_index('time_col', inplace=True)把时间列设为索引 - 如果时间列是字符串,先用
pd.to_datetime(df['time_col'])转成datetime,再设索引 - 检查是否成功:
df.index.dtype应返回datetime64[ns] - 若原始数据有重复时间戳或时区混乱,
resample()可能静默跳过或聚合异常,建议提前用df.index.is_monotonic_increasing和df.index.is_unique验证
按日/周/月聚合的核心参数是rule和how
resample()的rule参数决定分组粒度,how(或直接链式调用聚合函数)决定统计方式。不是所有缩写都等价,比如'M'是月末,'MS'才是月初;'W'默认周日结束,'W-MON'才按周一归组。
常用rule值与说明:
立即学习“Python免费学习笔记(深入)”;
-
'D':自然日,从00:00到23:59 -
'W':按周,终点为周日;如需周一,写'W-MON' -
'M':月末最后一天(如1月31日、2月28日) -
'MS':月初第一天(如1月1日、2月1日) -
'ME'等同于'M',语义更清晰,推荐用'ME'或'MS'
聚合操作建议直接链式调用,例如:df.resample('M').sum()、df.resample('W-MON').mean()。避免用how='mean'这种旧写法,已弃用。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
空日期补零还是跳过?用fill_method和closed控制
默认情况下,resample()只生成有数据的区间——比如某月没数据,结果里就不会出现那行。但做指标看板时往往需要补0或前向填充。
关键控制点:
- 加
closed='left'或closed='right'可调整区间闭合方向,影响边界数据归属(例如resample('M', closed='left')让1月1日00:00的数据计入1月,而非上月) - 补全所有日期用
.asfreq(fill_value=0),例如df.resample('D').sum().asfreq('D', fill_value=0) - 前向填充用
.ffill(),但注意它只填充NaN,不补缺失的索引位置;要先.asfreq()再.ffill() - 如果原始数据带时区,
resample()后索引可能丢失时区信息,需手动加.dt.tz_localize()或.dt.tz_convert()
高频数据降频时要注意采样精度丢失
比如每分钟采集一次的传感器数据,用resample('H').mean()算小时均值,看似合理,但若某小时只缺1分钟数据,默认会返回NaN。这在监控场景中容易误判离线。
解决办法:
- 用
min_count参数放宽阈值:df.resample('H').mean(min_count=55)表示至少有55个非空值才计算均值,否则填NaN - 用
origin参数对齐采样起点,避免因数据起始时间偏移导致首段窗口过短,例如resample('D', origin='start_day') - 对计数类指标(如每日请求数),优先用
.count()而非.size()——前者忽略NaN,后者统计所有行(含NaN) - 若需保留原始时间戳做调试,可在重采样前加一列
df['original_ts'] = df.index,聚合时用agg({'value': 'mean', 'original_ts': 'first'})
时间重采样的真正难点不在语法,而在理解业务周期与rule语义的匹配关系——比如“按自然周统计”和“按滚动7天统计”是两回事,后者得用rolling('7D')而不是resample('W')。

















