pandas.DataFrame.rolling().sum()是最直接的滑动窗口求和方法,需先按时间排序并设置min_periods=1避免开头NaN;时间窗口须用on参数指定datetime列并注意closed选项。

滑动窗口求和用 pandas.DataFrame.rolling().sum() 最直接
直接调用 rolling() 配合 sum() 是最稳妥的方式,不需要手动切片或循环。窗口大小填整数(比如 3 表示当前行及前两行),默认按索引顺序滚动,所以务必先按日期或时间排序——否则结果完全错乱。
常见错误是忘记排序,导致“最近3天”变成随机3行;另一个坑是未处理缺失值:min_periods=1 可让窗口在数据不足时仍返回部分和(比如第1行只有自己,就返回自身值),否则默认 min_periods=window,开头几行全是 NaN。
示例:
df = df.sort_values('date').reset_index(drop=True)
df['sales_3d_sum'] = df['sales'].rolling(3, min_periods=1).sum()
rolling().mean() 和 sum() 参数逻辑一致但结果类型不同
均值计算和求和共享同一套参数规则,区别只在最后调用 mean() 而非 sum()。注意:如果原始列含 NaN,rolling().mean() 默认跳过它们再算均值(即分母是有效值个数),而 sum() 同样跳过 NaN,不会补 0。
立即学习“Python免费学习笔记(深入)”;
若业务要求“缺一天就算无效,不参与均值”,就保持默认;若想强制要求窗口内至少有2个有效值才计算,改用 min_periods=2。
性能上无差异,但要注意 float 类型精度:均值结果自动转为 float64,即使输入是整数;如需保留整数显示,后续可 .round().astype(int),但别在累加前 round,会引入误差。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
用 numpy.convolve() 手写滑动和适合固定窗口+纯数值场景
当数据是纯一维 numpy.ndarray(比如只有一列销售额),且窗口不带时间对齐、也不需处理 NaN,numpy.convolve() 比 pandas 快不少。但它做的是卷积,不是严格意义的“窗口均值”,需要手动除以窗口长度。
关键点:
-
mode='valid'输出长度为n - window + 1,丢弃边缘;想对齐原数组长度,得用mode='same'并手动补首尾 - 权重必须是全 1 的数组,比如
np.ones(3),不能直接传数字3 - 它不识别时间戳,也不跳过
NaN—— 一旦输入含NaN,整个输出全NaN
示例(补首尾对齐):
import numpy as np vals = df['sales'].fillna(0).values window = 3 conv = np.convolve(vals, np.ones(window), mode='same') # 手动补前 window//2 个值(用首值)和后 window//2 个值(用末值) conv[:window//2] = vals[0] conv[-window//2:] = vals[-1] df['sales_conv_sum'] = conv
时间窗口(如 '7D')必须用 on 参数指定日期列
如果窗口要按日历天数(比如“过去7天销售额总和”),不能只靠行数滚动。必须用 rolling('7D', on='date'),且 date 列必须是 datetime64 类型。否则报错 ValueError: invalid on specified 或静默失效。
注意两点:
-
on不接受字符串列名以外的任何东西,哪怕你用df.set_index('date')了,也得显式写on='date',不能依赖索引 - 时间窗口默认左闭右开(
[t-7D, t)),若需包含当天,加closed='both'
示例:
df['date'] = pd.to_datetime(df['date'])
df['sales_7d_sum'] = df.rolling('7D', on='date', closed='both')['sales'].sum()时间对齐比行数对齐更贴近业务真实需求,但也更慢、更吃内存;一旦日期有重复或缺失,结果可能不符合直觉——比如同一天多条记录,滚动时会把它们全算进同一个窗口里。

















