You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 11:57:38