Pandas两DatetimeIndex数据帧向量化匹配比较及效率优化
高效实现方案
核心是用pandas内置的pd.merge_asof完成时间索引的前向匹配,搭配numpy.select做向量化条件判断,完全避免逐行循环,性能可以提升几十到上百倍。
具体实现步骤
1. 预处理(确保索引排序)
merge_asof要求两个输入数据的匹配键(这里就是DatetimeIndex)是升序排列的,你题目中已经说明数据是按时间排序的,保险起见可以先显式排序:
import pandas as pd import numpy as np # 按时间索引升序排序 df1 = df1.sort_index() df2 = df2.sort_index()
2. 批量匹配df2的行情数据
merge_asof的backward方向参数,刚好就是“取右表中索引小于等于左表当前索引的最后一行”的逻辑,直接完成你原来循环里的匹配操作:
# 左对齐匹配,仅拿df2的bid_price、ask_price两列 merged = pd.merge_asof( left=df1, right=df2[["bid_price", "ask_price"]], left_index=True, right_index=True, direction="backward" )
3. 向量化判断side字段
用np.select替代逐行if判断,批量给side列赋值:
# 定义判断条件和对应返回值 conditions = [ merged["price"] == merged["bid_price"], merged["price"] == merged["ask_price"], (merged["price"] > merged["bid_price"]) & (merged["price"] < merged["ask_price"]) ] choices = ["Bid", "Ask", "Inside"] # 条件匹配,未匹配到的默认返回Outside merged["side"] = np.select(conditions, choices, default="Outside") # 把结果赋值回原df1 df1["side"] = merged["side"]
性能说明
原有逐行循环的时间复杂度是O(N*M)(N为df1长度,M为df2长度),数据量过万后性能陡降。本方案的时间复杂度为O(N log M + N),即使是十万级别的数据量也可以在毫秒级完成运算。
如果存在df1某行的时间早于df2所有行的场景,匹配后bid_price和ask_price会为空,你可以根据业务需要提前过滤这类数据,或者在条件判断中增加空值处理逻辑即可。
内容的提问来源于stack exchange,提问作者John Holmes
相关产品推荐
相关产品推荐

