Python中rolling函数使用报错:ValueError: window必须为非负整数
问题描述
我编写了如下代码:
DF['AA'].rolling('90D').apply(calc_performance)
其中calc_performance函数定义为:
def calc_performance(x): if len(x) < 3: return np.nan else: return (x[-1] / x[0]) - 1
但运行时抛出错误:
ValueError: window must be an integer 0 or greater
我的DataFrame结构如下:
AA 2009-12-31 107.50 2010-01-04 106.40 2010-01-05 102.50 2010-01-06 106.90 2010-01-07 104.40 ... ... 2023-03-01 121.08 2023-03-02 124.12 2023-03-03 122.52 2023-03-06 128.19 2023-03-07 133.33
请问哪里操作出错了?
问题原因与解决方案
错误原因
pandas的rolling().apply()方法不支持时间偏移量(如'90D')作为窗口参数,该方法仅接受整数类型的窗口大小(即固定行数的滑动窗口),这就是触发ValueError的直接原因。
解决方案
根据你的需求,有两种高效的解决方式:
方式1:用内置方法替代apply(推荐)
你的计算逻辑是窗口内最后一个值与第一个值的比值减1,完全可以用rolling的last()和first()内置方法实现,无需使用apply(内置方法为向量化运算,性能远高于apply的循环计算):
import numpy as np # 计算90天窗口内首尾值的比值减1 result = (DF['AA'].rolling('90D').last() / DF['AA'].rolling('90D').first()) - 1 # 过滤窗口内数据不足3条的情况,替换为NaN result = result.where(DF['AA'].rolling('90D').count() >= 3, np.nan)
方式2:重采样后使用整数窗口+apply
如果你的自定义逻辑更复杂,必须使用apply,可以先将时间序列按天重采样(填补缺失日期),再用固定行数的窗口:
import numpy as np # 按天重采样,缺失值用前向填充(可根据业务需求调整填充策略) df_daily = DF.resample('D').ffill() # 使用90行作为窗口(对应90天),调用自定义函数 result = df_daily['AA'].rolling(90).apply(calc_performance) # 将结果还原回原DataFrame的时间索引 result = result.loc[DF.index]
内容的提问来源于stack exchange,提问作者TourEiffel
相关产品推荐
相关产品推荐

