ARIMA模型预测汇率输出NaN问题排查及任务求助
问题排查与任务完成:卢布对埃及英镑汇率预测
任务目标
- 基于交易日收盘数据构建俄罗斯卢布对埃及英镑的汇率走势图
- 选择最优ARIMA模型预测后续汇率值
- 将预测结果可视化并得出结论
现存问题
- 运行代码输出预测值时出现NaN,已确认原始数据无缺失但无法解决
- 当前代码错误处理**卢布对挪威克朗(NOK)**的数据,与任务要求的卢布对埃及英镑不符
问题排查与修正方案
1. 数据匹配错误修正
首先从数据文件中筛选**埃及英镑(EGP)**的对应数据,替换原代码中筛选NOK的逻辑:
# 原筛选NOK的代码替换为: if row[0] == 'EGP': dates.append(pd.to_datetime(int(row[2]), format='%Y%m%d')) rub_to_egp.append(float(row[6]))
同时修改数据框列名,确保一致性:
data = pd.DataFrame({'Date': dates, 'RUB_to_EGP': rub_to_egp})
2. NaN预测值排查与解决
预测出现NaN的核心原因及修复方式:
- 阶数选择不当:原代码直接使用
(3,1,0)阶数,未通过数据特征确定最优参数。建议用pmdarima的auto_arima自动筛选:from pmdarima import auto_arima stepwise_fit = auto_arima(data['RUB_to_EGP'], trace=True, suppress_warnings=True) model = sm.tsa.ARIMA(data['RUB_to_EGP'], order=stepwise_fit.order) - 日期频率不匹配:原预测用
freq='D'(自然日),但汇率数据仅包含交易日,应改用freq='B'(工作日频率):forecast_index = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=30, freq='B') - 模型收敛问题:若拟合时出现警告,可增加迭代次数:
model_fit = model.fit(maxiter=500)
3. 可视化修正
修正图表标题、坐标轴标签,匹配任务主题:
plt.title('俄罗斯卢布对埃及英镑汇率走势及ARIMA预测') plt.xlabel('日期') plt.ylabel('1埃及英镑兑换卢布数')
完整修正代码
import matplotlib.pyplot as plt import pandas as pd import csv import statsmodels.api as sm from statsmodels.tsa.stattools import adfuller from pmdarima import auto_arima def tundra(): print('1 - 显示图表') print('2 - 保存图表') oi = input('选择操作: ') if oi == '1': plt.show() elif oi == '2': po = input('输入保存文件名: ') plt.savefig(f'{po}.jpg') print(f'图表已保存为 {po}.jpg') else: print('输入无效,请重新选择') tundra() dates = [] rub_to_egp = [] # 读取数据并筛选埃及英镑数据,跳过格式错误行 with open('D:\\Teleegram dw\\mfdexport_1month_01012014_30082024.csv', 'r') as csvfile: plots = csv.reader(csvfile, delimiter=';') next(plots) for row in plots: if row[0] == 'EGP': try: dates.append(pd.to_datetime(int(row[2]), format='%Y%m%d')) rub_to_egp.append(float(row[6])) except ValueError: continue # 构建数据框并处理缺失值 data = pd.DataFrame({'Date': dates, 'RUB_to_EGP': rub_to_egp}) data.set_index('Date', inplace=True) print("检查数据中的NaN:") print(data.isnull().sum()) data.dropna(inplace=True) print("\n数据信息:") print(data.info()) print("\n数据前5行:") print(data.head()) # 平稳性检验 result = adfuller(data['RUB_to_EGP']) print('\nDickey-Fuller 平稳性检验结果:') print('统计量: %f' % result[0]) print('p值: %f' % result[1]) print('临界值:') for key, value in result[4].items(): print(f' {key}: {value}') # 自动筛选最优ARIMA模型 print('\n自动筛选最优ARIMA模型...') stepwise_fit = auto_arima(data['RUB_to_EGP'], trace=True, suppress_warnings=True, seasonal=False) print('\n最优模型摘要:') print(stepwise_fit.summary()) # 拟合模型并预测 model = sm.tsa.ARIMA(data['RUB_to_EGP'], order=stepwise_fit.order) model_fit = model.fit(maxiter=500) forecast = model_fit.forecast(steps=30) forecast_index = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=30, freq='B') forecast_df = pd.DataFrame(forecast, index=forecast_index, columns=['Forecast']) print("\n预测结果:") for index, row in forecast_df.iterrows(): print(f"日期: {index.strftime('%Y-%m-%d')}, 预测汇率: {row['Forecast']:.4f}") # 可视化 plt.figure(figsize=(25, 12), facecolor='grey') plt.gca().set_facecolor('black') plt.plot(data.index, data['RUB_to_EGP'], label='实际汇率 RUB/EGP', color='white', alpha=0.5, linewidth=2) plt.plot(forecast_df.index, forecast_df['Forecast'], label='ARIMA预测值', color='blue', linewidth=2, linestyle='--') plt.title('俄罗斯卢布对埃及英镑汇率走势及ARIMA预测') plt.xlabel('日期') plt.ylabel('1埃及英镑兑换卢布数') plt.legend() plt.grid(color='white', alpha=0.3) tundra()
结论
- 数据匹配错误是核心问题之一,必须确保筛选EGP而非NOK的数据
- 使用
auto_arima自动选择最优阶数,可避免手动选阶不当导致的预测NaN问题 - 预测日期使用工作日频率(
freq='B')更符合汇率交易日规律,减少模型适配误差 - 增加格式错误行的跳过逻辑,可提升数据质量,避免模型拟合失败
内容的提问来源于stack exchange,提问作者Faded Deer
相关产品推荐
相关产品推荐

