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

ARIMA模型预测周度销售数据时Matplotlib绘图报错求助

周度SARIMAX预测绘图报错问题分析与解决

背景情况

我使用SARIMAX(ARIMA类模型)预测某产品销量,数据为2015-01-01至2016-11-24的周度销售数据(CSV格式),需预测未来9周的销量。代码在月度数据上运行正常,但处理周度数据时绘图阶段出现错误。

CSV数据示例

"01-01-2015",9 "08-01-2015",8 "15-01-2015",13 "22-01-2015",10 "29-01-2015",12 "05-02-2015",5 "12-02-2015",4 "19-02-2015",6 "26-02-2015",9 "05-03-2015",3 "12-03-2015",3 "19-03-2015",2 ...

使用的代码

def parser(x): return datetime.datetime.strptime(x, '%d-%m-%Y')
fn = 'filename.csv'
y = pd.read_csv(fn, header = 0, parse_dates = [0], index_col = 0, squeeze = True, date_parser = parser)
newmod = sm.tsa.statespace.SARIMAX(y,order=(1, 1, 0),seasonal_order=(1, 1, 0, 12),enforce_stationarity=False,enforce_invertibility=False)
newresults = newmod.fit()
pred_uc = newresults.get_forecast(steps = 9)
pred_ci = pred_uc.conf_int()
y1 = pred_ci.iloc[:,0]
y2 = pred_ci.iloc[:,1]
ax = y.plot(label = "observed")
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index, pred_ci.iloc[:,0],pred_ci.iloc[:,1], color = 'k' , alpha = 0.5)
ax.set_xlabel('Date')
ax.set_ylabel('Sales count')
plt.legend()
plt.show()

报错信息

Traceback (most recent call last):
  File "H:\p36564\fit_net1.py", line 57, in <module>
    pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 2503, in __call__
    **kwds)
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 1927, in plot_series
    **kwds)
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 1729, in _plot
    plot_obj.generate()
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 258, in generate
    self._post_plot_logic_common(ax, self.data)
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 396, in _post_plot_logic_common
    fontsize=self.fontsize)
  File "H:\p36564\lib\site-packages\pandas\plotting\_core.py", line 470, in _apply_axis_properties
    labels = axis.get_majorticklabels() + axis.get_minorticklabels()
  File "H:\p36564\lib\site-packages\matplotlib\axis.py", line 1245, in get_majorticklabels
    ticks = self.get_major_ticks()
  File "H:\p36564\lib\site-packages\matplotlib\axis.py", line 1396, in get_major_ticks
    numticks = len(self.get_major_locator()())
  File "H:\p36564\lib\site-packages\matplotlib\dates.py", line 1249, in __call__
    self.refresh()
  File "H:\p36564\lib\site-packages\matplotlib\dates.py", line 1269, in refresh
    dmin, dmax = self.viewlim_to_dt()
  File "H:\p36564\lib\site-packages\matplotlib\dates.py", line 1026, in viewlim_to_dt
    .format(vmin))
ValueError: view limit minimum -36710.65 is less than 1 and is an invalid Matplotlib date value. This often happens if you pass a non-datetime value to an axis that has datetime units.

问题根源与解决办法

这个报错的核心原因其实很清晰:你给SARIMAX指定的季节性周期与周度数据不匹配,导致预测结果的索引不是合法的日期格式。

1. 修正季节性周期参数

你当前的seasonal_order=(1,1,0,12)里,最后一个参数12是月度数据的季节性周期(一年12个月),但周度数据的季节性周期应该是52(一年约52周)。把这个参数改成52,也就是seasonal_order=(1,1,0,52),这是解决问题的关键。

为什么这会引发绘图错误?因为当周期参数不匹配时,SARIMAX生成的预测索引可能无法正确解析为datetime类型,或者计算出的日期超出了Matplotlib可识别的日期范围,最终触发"无效日期值"的报错。

2. 额外验证与修复步骤

除了修改周期参数,你还可以做以下几步确保数据和预测索引的正确性:

  • 检查原始数据索引类型:运行print(y.index.dtype),确认输出是datetime64[ns],确保时间序列的索引格式正确。
  • 查看预测结果的索引:运行print(pred_uc.predicted_mean.index),确认这些日期是原始数据结束日期之后的连续9周,且为合法的datetime格式。
  • 如果索引仍有问题,可以手动生成未来日期并赋值:
    # 获取原始数据的最后一个日期
    last_date = y.index[-1]
    # 生成未来9周的日期序列(从下一周开始)
    future_dates = pd.date_range(last_date, periods=10, freq='W')[1:]
    # 给预测结果和置信区间设置正确的索引
    pred_uc.predicted_mean.index = future_dates
    pred_ci.index = future_dates
    

3. 检查CSV数据格式

你的CSV数据示例看起来是用空格分隔每个日期-销量对,这不符合标准CSV的格式(通常每行一条数据,或用逗号分隔字段)。如果你的原始CSV确实是这种格式,pd.read_csv可能无法正确解析数据,导致索引或数值异常。你可以检查y的结构(比如print(y.head())),确保它是一个正确的时间序列。如果解析有问题,可以调整pd.read_csv的参数,比如指定sep=' '来分隔数据。

修改季节性周期参数后,重新运行代码,应该就能正常完成绘图了。

内容的提问来源于stack exchange,提问作者Arkistarvh Kltzuonstev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:24:27