使用ARIMA预测股价时遇ufunc 'isnan'类型兼容错误求助
问题解决:ARIMA模型 TypeError: ufunc 'isnan' 不支持输入类型
错误原因
核心问题是循环调用arima_prediction时,传入的是股票代码字符串,而非DataFrame中对应的股价数据列。
看这段循环代码:
for stock in chosen_stocks: arima_prediction(stock)
这里的stock是字符串(比如'CTSH'),到了arima_prediction函数里,train_data, test_data = stock[3:int(len(dataframe) * 0.5)], stock[int(len(dataframe) * 0.5):]实际是对字符串做切片,得到的是单个字符组成的列表,并非数值型时间序列数据。ARIMA模型接收非数值类型数据后,内部调用np.isnan时自然报错,因为字符串无法进行空值判断。
修复步骤
只需修改循环部分,传入DataFrame中对应的列即可:
dataframe = get_data() for stock in chosen_stocks: arima_prediction(dataframe[stock]) # 改为传入dataframe的对应列
额外优化建议
- 函数内的
len(dataframe)应改为len(stock_series),因为函数接收的是单只股票的Series,用原DataFrame的长度会导致逻辑错误(比如单只股票数据长度与原DataFrame不一致时):
def arima_prediction(stock_series): # 用len(stock_series)代替len(dataframe) train_data, test_data = stock_series[3:int(len(stock_series) * 0.5)], stock_series[int(len(stock_series) * 0.5):] # 后续代码保持不变
- 可在函数开头添加类型检查,避免同类错误:
def arima_prediction(stock_series): if not isinstance(stock_series, pd.Series): raise ValueError("请传入Pandas Series类型的股价数据") # 后续代码
原问题信息
报错信息
None if faux_endog else np.any(np.isnan(self.endog))) TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
完整代码
# Imports import os import yfinance as yf import pandas as pd import numpy as np import matplotlib.pyplot as plt import io from PIL import Image import statsmodels.api as sm from statsmodels.tsa.arima.model import ARIMA from sklearn.metrics import mean_squared_error, mean_absolute_error import math from sklearn.preprocessing import MinMaxScaler import tensorflow as tf # Chosen stocks from NASDAQ-100 chosen_stocks = ['CTSH', 'BKNG', 'REGN', 'MSFT'] def get_data(): # Get list of tickers tickers = open("dataset/nasdaq_100_tickers.txt", "r") data = tickers.read().splitlines() # Check if the data has already been downloaded, drop NaN values if os.path.exists('dataframe.csv'): dataframe = pd.read_csv('dataframe.csv', index_col="Date", parse_dates=True).dropna() else: # Download Close data from Yahoo Finance data = yf.download(tickers=data, period='1y', interval='1d')['Close'] data.to_csv('dataframe.csv') # Convert array to Pandas dataframe, drop NaN values complete_data = data.dropna() dataframe = pd.DataFrame(complete_data) dataframe.drop(['GEHC'], axis=1, inplace=True) # Dropping GEHC because it contains NULL values return dataframe def arima_prediction(stock): train_data, test_data = stock[3:int(len(dataframe) * 0.5)], stock[int(len(dataframe) * 0.5):] train_arima = train_data test_arima = test_data history = [x for x in train_arima] y = test_arima predictions = list() model = ARIMA(history, order=(1, 1, 0)) model_fit = model.fit() forecast = model_fit.forecast()[0] predictions.append(forecast) history.append(y[0]) for i in range(1, len(y)): # Predict model = ARIMA(history, order=(1, 1, 0)) model_fit = model.fit() forecast = model_fit.forecast()[0] # Invert transformed prediction predictions.append(forecast) # Observation observation = y[i] history.append(observation) # Report performance mean_squared = mean_squared_error(y, predictions) print('Mean Squared Error: ' + str(mean_squared)) mean_absolute = mean_absolute_error(y, predictions) print('Mean Absolute Error: ' + str(mean_absolute)) root_mean_squared = math.sqrt(mean_squared_error(y, predictions)) print('Root Mean Squared Error: ' + str(root_mean_squared)) dataframe = get_data() for stock in chosen_stocks: arima_prediction(stock)
DataFrame样例
AAPL ABNB ... ZM ZS Date ... 2022-12-15 136.500000 90.610001 ... 70.199997 117.169998 2022-12-16 134.509995 89.570000 ... 69.860001 114.209999 2022-12-19 132.369995 85.930000 ... 69.089996 112.269997 2022-12-20 132.300003 87.620003 ... 68.559998 113.540001 2022-12-21 135.449997 87.070000 ... 69.930000 112.769997 ... ... ... ... ... ... 2023-11-28 190.399994 127.559998 ... 67.529999 193.850006 2023-11-29 189.369995 126.480003 ... 67.949997 199.839996 2023-11-30 189.949997 126.339996 ... 67.830002 197.529999 2023-12-01 191.240005 135.020004 ... 70.290001 198.029999 2023-12-04 188.669998 134.539993 ... 67.720001 197.919998
完整报错回溯
Traceback (most recent call last): File "C:/Users/xxx/source/repos/Project/main.py", line 370, in <module> arima_prediction(stock) File "C:/Users/xxx/source/repos/Project/main.py", line 217, in arima_prediction model = ARIMA(history, order=(1, 1, 0)) File "C:\Users\xxx\source\repos\Project\venv\lib\site-packages\statsmodels\tsa\arima\model.py", line 158, in __init__ self._spec_arima = SARIMAXSpecification( File "C:\Users\xxx\source\repos\Project\venv\lib\site-packages\statsmodels\tsa\arima\specification.py", line 458, in __init__ None if faux_endog else np.any(np.isnan(self.endog))) TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' Process finished with exit code 1
内容的提问来源于stack exchange,提问作者custardbun
相关产品推荐
相关产品推荐

