ARIMA预测后绘制柱状图遇数据类型不兼容问题求助
问题背景
使用ARIMA模型预测数据集未来5天的Amt数值,绘制包含现有数据与预测结果的柱状图时,触发类型不兼容错误。
示例数据集
CCY Pair Time Amt 0 GBPUSD 13/05/2023 1000 1 EURUSD 13/05/2023 2000 2 EURUSD 14/05/2023 3000 3 EURUSD 14/05/2023 5000 4 GBPEUR 15/05/2023 4000
报错详情
Traceback (most recent call last):
File "Graphs.py", line 46, in
plt.bar(combined_data.index, combined_data['Amt'])
File "/opt/homebrew/lib/python3.11/site-packages/matplotlib/pyplot.py", line 2439, in bar
return gca().bar(
^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/matplotlib/init.py", line 1442, in inner
return func(ax, *map(sanitize_sequence, args), **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/matplotlib/axes/_axes.py", line 2460, in bar
raise TypeError(f'the dtypes of parameters x ({x.dtype}) '
TypeError: the dtypes of parameters x (object) and width (float64) are incompatible
原代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.arima.model import ARIMA # The "Time" column contains the time periods, and "Amt" contains the values df = pd.read_csv("Data.csv") # Convert the "Time" column to a datetime type df['Time'] = pd.to_datetime(df['Time'], dayfirst=True) # Set the "Time" column as the index df.set_index('Time', inplace=True) # Sort the DataFrame by the index df.sort_index(inplace=True) df.index = pd.to_datetime(df.index).to_period('D') # Prepare the data for ARIMA modeling data = df['Amt'] # Fit the ARIMA model model = ARIMA(data, order=(1,0,0)) model_fit = model.fit() # Predict the next x periods x = 5 # Number of periods to predict predictions = model_fit.forecast(steps=x) # Generate the next x bar charts based on the predictions next_time_periods = pd.date_range(start=df.index.max().to_timestamp() + pd.DateOffset(days=1), periods=x, freq='D') # Generate x future time periods next_bar_charts = pd.DataFrame({'Time': next_time_periods, 'Amt': predictions}, index=next_time_periods) # Concatenate current and predicted bar chart data combined_data = pd.concat([df, next_bar_charts]) # Plot the combined bar chart plt.figure(figsize=(10, 6)) plt.bar(combined_data.index, combined_data['Amt']) plt.xlabel('Time') plt.ylabel('Amt') plt.xticks(rotation=45) # Rotate x-axis labels for better readability plt.show()
错误原因
索引类型不统一导致拼接后索引转为object类型,而matplotlib的plt.bar不支持该类型作为x轴参数:
- 原数据
df的索引是Period类型(通过to_period('D')转换) - 预测数据
next_bar_charts的索引是Datetime类型 - 拼接后
combined_data的索引自动转为object类型,触发类型不兼容报错。
解决方案
统一索引类型,确保原数据与预测数据的索引类型一致。以下提供两种可行方案:
方案1:统一为Datetime类型(推荐)
注释掉原代码中转换为Period索引的行,保留Datetime索引:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.arima.model import ARIMA df = pd.read_csv("Data.csv") # 转换Time列为datetime类型并设为索引 df['Time'] = pd.to_datetime(df['Time'], dayfirst=True) df.set_index('Time', inplace=True) df.sort_index(inplace=True) # 注释掉转换为Period索引的代码 # df.index = pd.to_datetime(df.index).to_period('D') # 准备ARIMA建模数据 data = df['Amt'] # 拟合ARIMA模型 model = ARIMA(data, order=(1,0,0)) model_fit = model.fit() # 预测未来5天 x = 5 predictions = model_fit.forecast(steps=x) # 生成未来时间周期(与原数据索引类型一致) next_time_periods = pd.date_range(start=df.index.max() + pd.DateOffset(days=1), periods=x, freq='D') next_bar_charts = pd.DataFrame({'Amt': predictions}, index=next_time_periods) # 拼接数据 combined_data = pd.concat([df, next_bar_charts]) # 绘制柱状图 plt.figure(figsize=(10, 6)) plt.bar(combined_data.index, combined_data['Amt']) plt.xlabel('时间') plt.ylabel('金额') plt.xticks(rotation=45) plt.tight_layout() # 防止标签被截断 plt.show()
方案2:统一为Period类型
将预测数据的索引转换为Period类型:
# 生成未来时间周期时转为Period类型 next_time_periods = pd.period_range(start=df.index.max() + pd.DateOffset(days=1), periods=x, freq='D') next_bar_charts = pd.DataFrame({'Amt': predictions}, index=next_time_periods)
内容的提问来源于stack exchange,提问作者Tom Pitts

