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

如何修复Python中statsmodels.tsa.statespace.SARIMAX代码的报错问题

解决SARIMAX拟合中的KeyError与索引单调性问题

先看你遇到的两个核心问题:KeyError: Timestamp('2016-06-01 00:00:00') 和 ValueError: index must be monotonic increasing or decreasing,我来逐个拆解并给出修复方案:

1. 时间切片越界导致KeyError

这个错误是最直接的:你的原始数据stand_data_full的时间范围只到2016-05-31 17:00,但当循环到time = 2016-05-31 17:00时,代码里的切片time + relativedelta(hours=7)会生成2016-06-01 00:00,这个时间戳不在你的原始数据索引里,所以抛出KeyError。

修复方法:

调整time_range的结束时间,确保所有time加上7小时后仍在原始数据的时间范围内。比如你要预测time+1到time+6,那么time的最晚值应该是原始数据的结束时间减去7小时(保证切片终点不越界),代码如下:

# 先获取原始数据的最大时间(假设stand_data_full的索引是时间戳)
max_data_time = stand_data_full.index.max()
# 调整time_range的结束时间:最晚的time要满足 time + relativedelta(hours=7) <= max_data_time
adjusted_end = max_data_time - relativedelta(hours=7)
time_range = pd.date_range(start_range, adjusted_end, freq='H')

如果你的原始数据确实只到2016-05-31 17:00,那adjusted_end就是2016-05-31 10:00,这样所有切片都不会越界。

2. 索引非单调导致的ValueError

这个错误说明stand_data_full的时间索引不是严格单调递增/递减的,pandas无法处理非单调索引的切片操作。

修复方法:

在使用数据前,强制对索引进行排序:

# 确保时间索引严格单调递增
stand_data_full = stand_data_full.sort_index()
# 可选:验证索引单调性,提前发现问题
assert stand_data_full.index.is_monotonic_increasing, "数据索引必须单调递增"

3. 优化切片写法,避免潜在问题

你当前的切片写法stand_data_full[cell] [time - ... : time + ...]存在空格,虽然语法上没问题,但用.loc进行标签索引更清晰、更可靠,也能减少索引相关的bug:

# 替换原来的endog和exog切片
start_slice = time - relativedelta(hours=60)
end_slice = time + relativedelta(hours=7)
endog_data = stand_data_full.loc[start_slice:end_slice, cell]
exog_data = stand_data_full.loc[start_slice:end_slice, feature_list]

model_fitted = sm.tsa.statespace.SARIMAX(
    endog=endog_data,
    exog=exog_data,
    order=(param[0], d, param[1]),
    seasonal_order=(param[2], D, param[3], S)
).filter(best_stand_model[zone].params)

4. 额外的验证步骤(可选)

为了确保每个循环的切片都有效,可以在循环内添加检查,跳过超出范围的时间:

for cell in tqdm_notebook(selected_cells):
    for time in time_range:
        start_slice = time - relativedelta(hours=60)
        end_slice = time + relativedelta(hours=7)
        # 检查切片范围是否在数据索引内
        if start_slice < stand_data_full.index.min() or end_slice > stand_data_full.index.max():
            print(f"跳过超出数据范围的时间: {time}")
            continue
        # 后续的模型拟合代码...

最终修改后的代码片段

把以上修改整合后,你的代码应该类似这样:

import statsmodels.api as sm 
import pandas as pd
from dateutil.relativedelta import relativedelta
from tqdm import tqdm_notebook

# 确保数据索引单调递增
stand_data_full = stand_data_full.sort_index()
assert stand_data_full.index.is_monotonic_increasing, "数据索引必须单调递增"

# 时间序列范围:2016.04.30 23:00 至 调整后的不越界时间
start_range = '2016-04-30 23:00:00'
max_data_time = stand_data_full.index.max()
end_range = max_data_time - relativedelta(hours=7)  # 调整结束时间
time_range = pd.date_range(start_range, end_range, freq='H')
print(f"调整后的time_range长度: {len(time_range)}")

forecast_juny = []
R = len(selected_cells)
for cell in tqdm_notebook(selected_cells):
    for time in time_range:
        start_slice = time - relativedelta(hours=60)
        end_slice = time + relativedelta(hours=7)
        
        n_kluster = labels[selected_cells.index(cell)] # 聚类编号
        zone = typical_zones[n_kluster] # 聚类对应的典型单元格
        param = best_param[zone]
        
        # 使用.loc进行可靠的切片
        endog_data = stand_data_full.loc[start_slice:end_slice, cell]
        exog_data = stand_data_full.loc[start_slice:end_slice, feature_list]
        
        model_fitted = sm.tsa.statespace.SARIMAX(
            endog=endog_data,
            exog=exog_data,
            order=(param[0], d, param[1]),
            seasonal_order=(param[2], D, param[3], S)
        ).filter(best_stand_model[zone].params)
        
        predicted_data = model_fitted.predict(time + relativedelta(hours=1), time + relativedelta(hours=6), dynamic=True)
        # 反标准化转换
        predicted_data = predicted_data * data_std[cell] + data_mean[cell]
        forecast_juny.append((time, predicted_data))
print('len(forecast_juny):', len(forecast_juny))

这样修改后,应该能解决你遇到的索引和越界问题,顺利得到预期的len(forecast_juny): 72930结果。

内容的提问来源于stack exchange,提问作者Ilya Ivanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:37