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

使用fbprophet指定cutoffs做交叉验证时触发ValueError报错

问题:Prophet交叉验证触发ValueError: Dataframe has no rows.

问题背景

时间序列数据范围为2017-01-01至2022-07-01,已完成fbprophet模型的创建与拟合。使用cross_validation函数指定cutoffs(生成月度时间点从2021-01-01到2022-06-01),尝试查看最近7个月的交叉验证结果时触发报错。

执行代码

df_cv2 = cross_validation(model=m, cutoffs=cutoffs, horizon='30 days')

完整报错栈

ValueError                                Traceback (most recent call last)
<ipython-input-323-75c1d39c86f3> in <module>
----> 1 df_cv2 = cross_validation(model=m, cutoffs=cutoffs, horizon='30 days')

C:\ProgramData\Anaconda3\lib\site-packages\prophet\diagnostics.py in cross_validation(model, horizon, period, initial, parallel, cutoffs, disable_tqdm)
    197 
    198     else:
---> 199         predicts = [
    200             single_cutoff_forecast(df, model, cutoff, horizon, predict_columns)
    201             for cutoff in (tqdm(cutoffs) if not disable_tqdm else cutoffs)

C:\ProgramData\Anaconda3\lib\site-packages\prophet\diagnostics.py in <listcomp>(.0)
    198     else:
    199         predicts = [
---> 200             single_cutoff_forecast(df, model, cutoff, horizon, predict_columns)
    201             for cutoff in (tqdm(cutoffs) if not disable_tqdm else cutoffs)
    202         ]

C:\ProgramData\Anaconda3\lib\site-packages\prophet\diagnostics.py in single_cutoff_forecast(df, model, cutoff, horizon, predict_columns)
    251         for props in m.seasonalities.values()
    252         if props['condition_name'] is not None])
---> 253     yhat = m.predict(df[index_predicted][columns])
    254     # Merge yhat(predicts), y(df, original data) and cutoff
    255 

C:\ProgramData\Anaconda3\lib\site-packages\prophet\forecaster.py in predict(self, df)
   1202         else:
   1203             if df.shape[0] == 0:
-> 1204                 raise ValueError('Dataframe has no rows.')
   1205             df = self.setup_dataframe(df.copy())
   1206 

ValueError: Dataframe has no rows.

数据框样例

y   ds
0      -1.0 2017-01-01
978     2.0 2017-02-01
1582    0.0 2017-03-01
2237    0.0 2017-04-01
2902    0.0 2017-05-01

cutoff生成代码与结果

cutoffs = pd.date_range(start='2021-01-01', end='2022-06-01', freq='1MS')

生成的cutoffs:

DatetimeIndex(['2021-01-01', '2021-02-01', '2021-03-01', '2021-04-01',
               '2021-05-01', '2021-06-01', '2021-07-01', '2021-08-01',
               '2021-09-01', '2021-10-01', '2021-11-01', '2021-12-01',
               '2022-01-01', '2022-02-01', '2022-03-01', '2022-04-01',
               '2022-05-01', '2022-06-01'],
              dtype='datetime64[ns]', freq='MS')

报错原因分析

  1. 时间范围超出边界:原始数据截止到2022-07-01,当cutoff为2022-06-01时,horizon='30 days'要求预测到2022-07-01之后的时间点,但原始数据中没有该范围内的观测值,导致生成的预测用Dataframe为空。
  2. 时间粒度不匹配:数据是月度频率(每月一条记录),但horizon使用了30 days,可能出现时间点不匹配的情况,找不到对应日期的观测数据。

解决方法

方法1:调整cutoffs的结束时间

将cutoffs的结束时间提前,确保cutoff加上horizon不超过数据的最大时间:

cutoffs = pd.date_range(start='2021-01-01', end='2022-05-01', freq='1MS')

方法2:匹配时间粒度设置horizon

因为数据是月度的,将horizon改为月度单位,避免时间点匹配问题:

df_cv2 = cross_validation(model=m, cutoffs=cutoffs, horizon='1 month')

方法3:自动过滤无效cutoffs

提前筛选出那些cutoff + horizon不超过数据最大时间的有效cutoffs:

max_ds = df['ds'].max()
horizon = '30 days'
valid_cutoffs = [cutoff for cutoff in cutoffs if cutoff + pd.Timedelta(horizon) <= max_ds]
df_cv2 = cross_validation(model=m, cutoffs=valid_cutoffs, horizon=horizon)

内容的提问来源于stack exchange,提问作者Mohamed Najb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:48:26