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

使用yfinance做SARIMAX股票预测时matplotlib绘图异常如何解决

问题描述

使用yfinance API获取亚马逊(AMZN)的股票历史数据,搭建SARIMAX模型做股价走势预测,模型拟合和预测步骤运行正常,仅在matplotlib绘图环节出现异常:预期将历史收盘价序列与预测均值序列绘制在同一张图中,预测值衔接在最新历史价格之后,符合常规预测图的展示效果。但实际运行代码后,历史价格与预测值两个序列分别显示在图表的不同位置,没有成功衔接。
我的绘图结果

原有代码
import yfinance as yf
ticker = yf.Ticker("AMZN")
history = ticker.history(period="max")
import matplotlib.pyplot as plt
import statsmodels.api as sm
model=sm.tsa.statespace.SARIMAX(history['Close'],order=(1, 1, 1),seasonal_order=(1,1,1,12))
results=model.fit()
prediction = results.get_forecast(steps=12)
pred_ci = prediction.conf_int()
ax = history['Close'].plot(label='observed', figsize=(14, 4))
prediction.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.25)
plt.legend()
plt.show()
问题原因

yfinance返回的历史数据索引为带时区信息的datetime格式,而SARIMAX生成的预测结果索引为无时区的datetime格式,两类索引无法被matplotlib识别为连续的时间轴,最终导致两个序列错位显示。

解决方法

在获取历史数据后,新增一行代码统一时间索引格式,移除历史数据索引的时区信息即可:

history.index = history.index.tz_localize(None)
修改后可正常运行的代码
import yfinance as yf
import matplotlib.pyplot as plt
import statsmodels.api as sm

ticker = yf.Ticker("AMZN")
history = ticker.history(period="max")
# 移除索引的时区信息,统一时间格式
history.index = history.index.tz_localize(None)

model=sm.tsa.statespace.SARIMAX(history['Close'],order=(1, 1, 1),seasonal_order=(1,1,1,12))
results=model.fit()
prediction = results.get_forecast(steps=12)
pred_ci = prediction.conf_int()

ax = history['Close'].plot(label='observed', figsize=(14, 4))
prediction.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
                pred_ci.iloc[:, 0],
                pred_ci.iloc[:, 1], color='k', alpha=.25)
plt.legend()
plt.show()

运行修改后的代码,历史价格序列和预测序列就可以正常衔接,置信区间也会对应展示在预测区间范围内。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:24:03