ARIMA预测中如何为seasonal_decompose传入多变量并优化时间轴?
多变量季度时间序列分解与可视化解决方案
一、解决seasonal_decompose多变量报错问题
seasonal_decompose本身仅支持单变量输入,直接传入多列DataFrame必然触发KeyError或TypeError。可以通过批量处理+统一可视化的方式整合多变量结果:
1. 批量处理多变量分解
先确保你的时间序列索引是季度频率的DatetimeIndex,再循环处理每个变量并保存分解结果:
import pandas as pd from statsmodels.tsa.seasonal import seasonal_decompose import matplotlib.pyplot as plt # 示例数据:索引为季度日期,包含HR、Legal、Fin三列 df = pd.DataFrame({ 'HR': [120, 130, 125, 140, 145, 150, 148, 160, 165, 170, 168, 180], 'Legal': [80, 85, 82, 90, 95, 98, 96, 105, 108, 110, 109, 120], 'Fin': [200, 210, 205, 220, 225, 230, 228, 240, 245, 250, 248, 260] }, index=pd.date_range(start='2020Q1', periods=12, freq='Q')) # 存储所有变量的分解结果 decompose_results = {} for col in df.columns: # 季度数据period固定为4 result = seasonal_decompose(df[col], model='additive', period=4) decompose_results[col] = result
2. 生成统一整合图表
用子图布局将所有变量的分解组件(原始数据、趋势、季节、残差)整合到一张画布中:
# 根据变量数量设置子图布局 fig, axes = plt.subplots(nrows=len(df.columns), ncols=4, figsize=(16, len(df.columns)*3)) # 遍历每个变量的分解结果,逐个绘制子图 for i, (col, result) in enumerate(decompose_results.items()): # 原始数据 result.observed.plot(ax=axes[i,0], title=f'{col} - 原始数据') # 趋势项 result.trend.plot(ax=axes[i,1], title=f'{col} - 趋势') # 季节项 result.seasonal.plot(ax=axes[i,2], title=f'{col} - 季节') # 残差项 result.resid.plot(ax=axes[i,3], title=f'{col} - 残差') # 调整子图间距,避免重叠 plt.tight_layout() plt.show()
二、设置X轴显示日期/季度
要让X轴显示季度或日期格式,核心是确保时间序列索引为DatetimeIndex并设置正确频率:
- 转换索引格式(如果当前索引是字符串或数字):
# 若原始索引是"2020Q1"这类字符串,先转为DatetimeIndex df.index = pd.to_datetime(df.index) # 显式设置季度频率 df = df.asfreq('Q')
- 自定义X轴标签格式,让显示更清晰:
from matplotlib.dates import DateFormatter # 在子图绘制循环中添加以下代码,针对每个子图的X轴 date_form = DateFormatter("%Y-Q%q") axes[i,0].xaxis.set_major_formatter(date_form) axes[i,1].xaxis.set_major_formatter(date_form) axes[i,2].xaxis.set_major_formatter(date_form) axes[i,3].xaxis.set_major_formatter(date_form) # 旋转标签避免重叠 for ax in axes[i,:]: ax.tick_params(axis='x', rotation=45)
三、快速对比同类型组件
如果需要单独对比所有变量的趋势/季节/残差,可以将同类型组件整合到一个DataFrame后统一绘图:
# 整合所有变量的趋势项 trend_df = pd.DataFrame({col: res.trend for col, res in decompose_results.items()}) trend_df.plot(figsize=(12,6), title='所有变量的趋势对比') # 设置X轴格式 plt.gca().xaxis.set_major_formatter(DateFormatter("%Y-Q%q")) plt.xticks(rotation=45) plt.show()
内容的提问来源于stack exchange,提问作者Scythor
相关产品推荐
相关产品推荐

