使用Pandas循环+TensorFlow预测价格时DataFrame无法追加问题
问题解决与优化方案
问题原因
- Pandas
append()非原地修改:该方法不会直接修改原DataFrame,而是返回包含新行的新对象,必须将结果重新赋值给last_data才会生效。 - 追加行格式错误:直接传入
[nextdate, pred_price]无法匹配原DataFrame的列结构,需要构造对应列名的字典或Series。 - 日期未更新循环依赖:由于原DataFrame始终未被修改,每次循环都读取初始最后一行的日期,导致新日期重复生成同一天。
修正后的代码
import pandas as pd import numpy as np last_data = pd.read_excel("Nickel.xlsx") print('Old dataset before loop : ', last_data) for i in range(10): new_df = last_data.filter(['Valeur']) # 修正:取最后60行数据,原代码的-60+(-i)会导致每次取的行数递减,不符合滚动预测逻辑 last_60_days = new_df[-60:].values last_60_days_scaled = scaler.transform(last_60_days) # 简化X_test构造 X_test = np.array([last_60_days_scaled]) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1)) pred_price = model.predict(X_test) pred_price = scaler.inverse_transform(pred_price)[0][0] # 提取数值,避免二维数组 dernieredate = last_data['Date'].iloc[-1] datecorrect = pd.to_datetime(dernieredate) nextdate = datecorrect + pd.to_timedelta(1, unit='d') print('Old date : ', datecorrect) print('New date : ', nextdate) # 构造符合列结构的行并追加,同时重新赋值给last_data new_row = pd.DataFrame({'Date': [nextdate], 'Valeur': [pred_price]}) last_data = pd.concat([last_data, new_row], ignore_index=True) print('New dataset final after loop : ', last_data)
关键修正点说明
- 使用
pd.concat()替代append()(Pandas 2.0+已弃用append()),并将结果重新赋值给last_data以更新原数据集。 - 构造包含列名的DataFrame作为新行,确保结构与原数据集完全匹配。
- 修正了
last_60_days的切片逻辑:原代码-60+(-i)会导致每次循环取的行数递减(第一次50行,第二次40行...),不符合滚动预测需要的最近60行数据要求。 - 提取
pred_price的单个数值,避免将二维数组存入DataFrame造成数据结构混乱。
优化建议
- 批量收集结果再合并:循环中反复修改DataFrame效率极低,建议先创建列表存储所有预测的日期和价格,最后一次性合并到原DataFrame:
predictions = [] for i in range(10): # ... 执行预测逻辑 ... predictions.append({'Date': nextdate, 'Valeur': pred_price}) # 最后一次性合并所有预测结果 last_data = pd.concat([last_data, pd.DataFrame(predictions)], ignore_index=True)
- 提前生成所有预测日期:避免循环中重复计算日期,直接生成连续日期序列:
start_date = last_data['Date'].iloc[-1] + pd.to_timedelta(1, unit='d') pred_dates = pd.date_range(start=start_date, periods=10)
- 处理非交易日:如果是金融时间序列,可使用
pandas.bdate_range()生成工作日日期,自动跳过周末和节假日。 - 简化特征处理:将X_test的构造简化为一行代码,减少冗余:
X_test = np.reshape(last_60_days_scaled, (1, 60, 1))
内容的提问来源于stack exchange,提问作者Adam Ben kahla
相关产品推荐
相关产品推荐

