rolling() 方法在 pandas 0.18.0 及以上版本才支持;若报 attributeerror,说明版本过低,需升级 pandas 至 0.18.0+。

rolling() 函数怎么写才不报错
直接调用 rolling() 却提示 AttributeError: 'Series' object has no attribute 'rolling'?那说明你用的是太老的 Pandas 版本(Series 或 DataFrame。检查类型用 type(df['col']),别假设它自动是 Series。
常见错误是:对 list、numpy array 或 dict 直接调 .rolling(5) —— 它只认 Pandas 自己的数据结构。
- 必须先确保数据在
Series或DataFrame中,比如df['price'].rolling(5) - 窗口大小必须是正整数或
pd.Timedelta(时间窗口),不能是浮点数或字符串 - 如果列含
NaN,默认不跳过;想跳过得加参数min_periods=1,否则前几行全为NaN
移动平均线计算结果全是 NaN
这不是 bug,是 rolling() 的默认行为:当窗口内有效值数量不足 min_periods(默认等于窗口大小)时,就填 NaN。比如 rolling(5).mean(),前 4 行必然为 NaN。
真实交易场景中,你通常希望从第 5 个点开始有值,但也要小心——如果原始数据开头就有大量 NaN,那整个滚动结果可能持续为空。
- 显式设
min_periods=1可让首个非空值就出结果,但要注意这会改变指标意义(早期均值仅基于 1~2 个点) - 时间序列中更稳妥的是用
closed='right'(默认),避免把未来数据卷进来 - 若用日期索引但未排序,
rolling()不保证按时间顺序计算,务必先df.sort_index()
不同 window 类型对性能和结果的影响
rolling(5) 是固定长度窗口,快且直观;但遇到不等距时间数据(比如日频里跳过周末),就得换 rolling('5D') 这类时间偏移窗口——它按真实时间跨度取数,不是按行数。
后者慢得多,尤其数据量大时,因为每行都要向前查时间范围,还要求索引是 DatetimeIndex 且已排序。
-
rolling(5):纯位置索引,无依赖,最快 -
rolling('5D'):需df.index = pd.to_datetime(df.index),且df.sort_index()必须做 -
rolling('5B')(5 个工作日)比'5D'更慢,内部要调用工作日逻辑判断
apply() 里自定义函数为什么返回维度错乱
用 rolling(5).apply(lambda x: np.percentile(x, 95)) 看似没问题,但一旦 x 含 NaN,np.percentile 默认不忽略,结果直接是 NaN。更隐蔽的问题是:如果 lambda 返回标量,Pandas 能对齐;但如果返回数组(比如 lambda x: x[:-1]),就会崩。
自定义函数输出必须是单个数值,否则 rolling().apply() 会抛 ValueError: Must produce aggregated result。
- 优先用内置方法:
.mean()、.std()、.quantile(0.95),它们自动处理NaN和类型 - 真要用
apply,函数末尾加return float(result)强制标量化 - 调试时可临时加
print(len(x), x.tolist())查看每次传入的窗口内容
滚动计算最易被忽略的其实是索引对齐——尤其是 merge 或 concat 后没重置索引,rolling() 仍按原索引算,看着像结果偏移,其实只是位置没对上。










