pandas.DataFrame.rolling 为时间序列设计,自动处理索引对齐、缺失值和边界行为,是滑动窗口最安全的计算方法,默认按顺序滑动,window=20 表示 20 交易日,需要 resample 按自然日计算填充;min_periods=1 当数据不足时,可以返回部分平均值;rolling().mean() 快速稳定,必须使用复杂的逻辑 rolling().apply(),但不支持 min_periods 而且性能低。计算滑动窗
pandas.DataFrame.rolling 最直接
直接调用 rolling 这是最安全的方法,专门为时间序列设计,自动处理索引对齐、缺失值和边界行为。不要自己写 for 循环或用 numpy.convolve 手动实现-容易错位,不兼容 NaN、原始时间戳不能保留。
-
rolling默认情况下,如果数据已按日期上升顺序排列(df.index是DatetimeIndex),结果自然对齐 - 窗口大小用
window=20表示 20 交易日不是日历日;如果需要自然日(如 20 必须先用日历日)resample('D').first()填充再计算 - 遇到停牌或缺价时,
min_periods=1可使窗户不足 20 条数据仍返回部分平均值,否则返回 NaN)
rolling().mean() 和 rolling().apply() 的关键区别
rolling().mean() 快速稳定,适用于标准移动平均;但是,如果需要计算加权平均、中位数或自定义逻辑(如排除最高和最低平均值),则必须使用 rolling().apply(),但要注意性能和边界。
-
apply默认传入Series,函数不能依赖全局变量或外部变量 DataFrame —— 否则,多进程或 chunk 情况下会出错 - 例如计算「去极值后的 20 日均值」:
lambda x: x.clip(lower=x.quantile(0.1), upper=x.quantile(0.9)).mean(),但每次都要重算分位数,慢;建议在使用之前预计计算阈值rolling().agg() -
apply不支持min_periods参数需要在函数中手动判断len(x) 并返回 <code>np.nan
从接口拉下股票数据往往是倒序(最新在前),而 rolling 按索引顺序滑动。如果没有排序,20 日均线实际上是“未来” 20 天”的平均值完全逆转。
Python 3.14.2
Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。
下载- 检查顺序:
df.index.is_monotonic_increasing,不满意就先执行df = df.sort_index() - 更安全的方法:无论原始顺序如何,统一使用
df.sort_values('date').set_index('date')构建索引 - 一些市场界面(例如 akshare)返回的 DataFrame 默认无索引,必须设置显式设置
set_index('date'),否则rolling按整数位置滑动,与日期无关
连续三次 df['close'].rolling(5).mean()、.rolling(10).mean()、.rolling(20).mean() 三次独立窗口扫描会触发,IO 和 CPU 浪费明显。
立即学习“Python免费学习笔记(深入);
- 用
agg一次完成:df['close'].rolling(20).agg(['mean', lambda x: x.rolling(10).mean().iloc[-1], lambda x: x.rolling(5).mean().iloc[-1]])—— 但嵌套 rolling 不推荐 - 正确做法:分别定义三个窗口,但重用同一列:
df[MA5] = df['close'].rolling(5).mean()、df[MA10] = df['close'].rolling(10).mean(),底层 pandas 多次优化单列 rolling - 若要批量生成,用字典推导:
{f'MA{n}': df['close'].rolling(n).mean() for n in [5, 10, 20]},再pd.concat(..., axis=1)
rolling 默认行为可能不符合商业语义——你必须看清楚「到今天为止 N 天均值」,还是「包括今天 N 天中心均值」,后者得用 center=True。