如何为DataFrame每行生成匹配股价的NumPy数组并解决KeyError报错
问题原因
你遇到的KeyError核心原因是交易记录里的对应日期不存在于你下载的个股行情数据中:大概率是当天为周末/节假日休市,没有交易行情记录,所以用df.loc[不存在的日期]直接抛出键错误。
修复方案
可以按以下步骤实现你要的效果,同时规避报错,逻辑更简洁:
- 先把个股行情的日期设为索引(你已经做了这步)
- 对每笔交易,先判断日期是否在行情索引里,跳过不存在的日期(或者你可以调整为匹配最近的交易日,按需选择)
- 生成对应数组的时候直接用索引匹配,不需要额外加row_num列
可直接运行的示例代码(适配你给的补充测试用例)
import pandas as pd import numpy as np # 你的测试数据 trade_data = [['ASO', '5/5/21', 10], ['ASO', '5/7/21', 12], ['RBLX', '5/7/21', 15]] trade_df = pd.DataFrame(trade_data, columns = ['Code', 'Date', 'Price']) trade_df['Date'] = pd.to_datetime(trade_df['Date']) aso_data = [['5/5/21', 12, 5, 10, 7], ['5/6/21', 15, 7, 13, 8], ['5/7/21', 17, 10, 15, 11]] aso_df = pd.DataFrame(aso_data, columns = ['Date', 'High', 'Low', 'Open', 'Close']) aso_df['Date'] = pd.to_datetime(aso_df['Date']) aso_df = aso_df.set_index('Date') # 行情数据日期设为索引 def generate_trade_arrays(code, trade_df, quote_df): # 筛选对应个股的交易 stock_trades = trade_df[trade_df['Code'] == code].reset_index(drop=True) trade_arrays = [] for _, row in stock_trades.iterrows(): trade_date = row['Date'] # 先判断日期是否存在于行情数据中,不存在可以跳过或者做兼容处理 if trade_date not in quote_df.index: print(f"警告:{code} 在 {trade_date.strftime('%Y-%m-%d')} 无行情数据,跳过该笔交易") continue # 初始化全NaN数组,长度和行情数据一致 arr = np.full(len(quote_df), np.nan) # 找到对应日期的位置赋值 arr[quote_df.index.get_loc(trade_date)] = row['Price'] trade_arrays.append(arr) return trade_arrays # 测试ASO的输出 aso_trade_arrays = generate_trade_arrays('ASO', trade_df, aso_df) print(aso_trade_arrays) # 输出为 [array([10., nan, nan]), array([nan, nan, 12.])] 完全符合你的预期
适配你原有业务逻辑的修改点
对应你原来的代码,只需要做几处调整:
- 去掉新增
row_num列的冗余逻辑,直接用quote_df.index.get_loc(日期)获取位置 - 增加日期存在性判断,避免KeyError
- 不需要额外构造
simpDataFrame,直接用分组后的交易数据遍历即可
可选优化:匹配最近交易日
如果希望休市日的交易自动匹配最近的前一个交易日,可以把日期存在性判断的部分替换为:
if trade_date not in quote_df.index: # 取小于等于交易日期的最近一个交易日 trade_date = quote_df.index[quote_df.index <= trade_date].max() if pd.isna(trade_date): print(f"警告:{code} 没有早于交易日期的行情数据,跳过该笔交易") continue
内容的提问来源于stack exchange,提问作者spring_chicken
相关产品推荐
相关产品推荐

