rolling 算出全 NaN 主因是索引非 DatetimeIndex 或未排序;时间窗口(如 '7D')要求索引为排序后的 datetime64[ns],否则无法对齐;非时间窗口(如 5)仅按行数滑动,不依赖索引。

rolling 为什么算出来全是 NaN?检查 index 和 freq 是否对齐
常见错误是直接对无序或非时间索引的 DataFrame 调用 rolling(window='7D'),结果全为 NaN。Pandas 的时间窗口(如 '7D')要求索引是 DatetimeIndex 且已排序,否则无法按时间对齐滑动。
- 先确认索引类型:
df.index.dtype应为datetime64[ns] - 若原始数据是列而非索引,需先设为索引:
df.set_index('date_col', inplace=True) - 务必排序:
df = df.sort_index(),否则rolling按原始行序滑动,不是按时间滑动 - 非时间窗口(如
rolling(5))只认行数,不依赖 index,适合数值序列或已按序排列的指标
expanding 和 rolling 的本质区别:累积 vs 固定长度
expanding() 是从第一行开始累积计算,窗口长度逐行增长;rolling(window=3) 始终只看最近 3 行(或 3 个时间单位)。二者语义不同,不能混用替代。
-
df['col'].expanding().mean()第 1 行 = 第 1 行值,第 2 行 = 前 2 行均值,第 n 行 = 前 n 行均值 -
df['col'].rolling(3).mean()前 2 行固定返回NaN(因不足 3 个),第 3 行起才开始有值 - 想实现“至少 2 个点就出结果”,可加
min_periods=2参数:rolling(3, min_periods=2) -
expanding不支持时间偏移(如'7D'),只接受整数或None
groupby 后做 rolling:必须用 apply + lambda,不能链式调用
对分组数据做滑动计算时,df.groupby('category').rolling(5)['value'].mean() 看似合理,但实际会报 KeyError 或返回错乱结构——因为 rolling 在 groupby 后不直接支持列选择语法。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 正确写法:
df.groupby('category')['value'].apply(lambda x: x.rolling(5).mean()) - 若需保留原始索引(避免多级索引),加
reset_index(name='rolling_mean') - 性能注意:
apply是 Python 循环,大数据量时比向量化慢;若分组多、每组小,影响不大;若每组很大,考虑先sort_values再整体rolling加布尔掩码过滤 - 时间窗口分组滚动(如每组内按天滚动 7 天)更复杂,需确保组内 index 是
DatetimeIndex且已排序
rolling 计算后如何对齐结果?center 参数和 closed 选项常被忽略
默认 rolling(window=3) 的结果中,第 3 行对应的是第 1–3 行的计算值,即右对齐(closed='right')。但有时你需要中心对齐(比如画图时希望均值标在中间时间点),或左闭右开等语义。
立即学习“Python免费学习笔记(深入)”;
- 中心对齐:
rolling(3, center=True)→ 窗口为 [i-1, i, i+1],结果放在第 i 行,前/后各缺 1 行为NaN - 控制闭合方式:
rolling(3, closed='left')表示取 [i-3, i-2, i-1],结果放第 i 行;closed='both'(默认)取 [i-2, i-1, i] - 时间窗口下
closed更关键,例如rolling('7D', closed='left')不包含当前时刻,适合避免数据泄露场景 - 所有这些参数不影响计算逻辑,只改变“哪几行参与计算”以及“结果落在哪一行”
closed 和 center 的语义误读——它们不改数值,只改对齐方式,但一旦画图或拼接就立刻暴露。

















