Pandas中为Trade行匹配对应时间偏移点Quote的Vol_imb高效方案
高效解决方案:利用pandas的merge_asof批量匹配
核心思路
放弃逐行循环,改用pandas的merge_asof进行向量化匹配——这是专门为“按时间找最近前序记录”场景设计的高效工具,底层用C实现,性能远超Python循环。
步骤实现
1. 数据预处理
首先分离交易(trade)和报价(quote)数据,确保所有时间列都是datetime类型:
import pandas as pd # 确保原始时间列和偏移时间列都是datetime格式 df['timestamp'] = pd.to_datetime(df['timestamp']) time_offset_cols = ['-2ms', '-1ms', '1ms', '2ms'] df[time_offset_cols] = df[time_offset_cols].apply(pd.to_datetime) # 分离trade和quote数据集 trades = df[df['type'] == 'trade'].copy().reset_index(drop=True) quotes = df[df['type'] == 'quote'][['timestamp', 'vol_imb']].copy() # merge_asof要求右表(quotes)必须按时间排序 quotes = quotes.sort_values('timestamp').reset_index(drop=True)
2. 转换为长格式批量处理
将trade的四个时间偏移列转为长格式,这样可以一次性处理所有时间点的匹配:
# 把trade的多列时间偏移转为长格式,每行对应一个时间偏移点 trades_long = trades.melt( id_vars=['timestamp', 'execution_size', 'price', 'aggressor_side', 'type'], value_vars=time_offset_cols, var_name='time_offset', value_name='offset_timestamp' ).dropna(subset=['offset_timestamp']).reset_index(drop=True)
3. 用merge_asof匹配最新quote
使用merge_asof找到每个偏移时间点之前最新的quote的vol_imb:
# 按时间匹配每个offset_timestamp之前的最新quote matched = pd.merge_asof( trades_long.sort_values('offset_timestamp'), quotes, left_on='offset_timestamp', right_on='timestamp', direction='backward' # 找<=offset_timestamp的最近记录 ) # 整理匹配结果,为后续转宽格式做准备 matched = matched.rename(columns={'vol_imb': 'matched_vol_imb'})
4. 转回宽格式并合并
将长格式的匹配结果转回宽格式,对应每个trade行的四个偏移列:
# 转回宽格式,每个trade行对应四个vol_imb结果列 matched_wide = matched.pivot( index='timestamp', columns='time_offset', values='matched_vol_imb' ).reset_index().rename_axis(None, axis=1) # 合并回原trade数据 final_trades = pd.merge(trades, matched_wide, on='timestamp', how='left') # (可选)合并回原始全量DataFrame,保留所有行 final_df = pd.merge(df, final_trades[['timestamp'] + list(matched_wide.columns[1:])], on='timestamp', how='left')
验证结果
查看处理后的trade数据,与预期输出一致:
print(final_trades[['timestamp', '-2ms', '-1ms', '1ms', '2ms']])
输出:
timestamp -2ms -1ms 1ms 2ms 0 2023-09-08 07:00:01.501007685 0.80 0.80 0.03 0.03 1 2023-09-08 07:00:01.506418594 0.03 0.13 -0.00 -0.00
性能优势
merge_asof是向量化操作,避免了Python逐行循环的巨大开销,处理百万级数据时速度比iterrows快数十倍甚至上百倍。- 代码更简洁,逻辑清晰,易于维护和扩展。
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

