Pandas如何根据另一DataFrame的最近时间筛选对应行数据
批量按最近时间匹配DataFrame行实现方案
直接用pandas内置的merge_asof方法即可完成批量最近邻时间匹配,无需逐行循环查询,性能远高于单值匹配方案,完全满足批量筛选需求。
注意:使用前必须确保两个DataFrame的时间列已转为
datetime64类型,且均按时间列做升序排序,否则匹配结果会出错。
实现代码
import pandas as pd # ---------------------- # 此处替换成你自己的df1、df2读取逻辑即可 # 示例数据构造 df1 = pd.DataFrame({ 'Date': pd.to_datetime([ '2015-02-24 00:00:02', '2015-02-24 00:01:15', '2015-02-24 00:02:22', '2015-02-24 00:03:39', '2015-02-24 00:04:00' ]), 'Val': [1.764052, 0.400157, 0.978738, 2.240893, 1.867558] }) df2 = pd.DataFrame({ 'Date': pd.to_datetime([ '2015-02-24 00:00:00', '2015-02-24 00:01:00', '2015-02-24 00:02:00', '2015-02-24 00:03:00', '2015-02-24 00:04:00', '2015-02-24 00:05:00' ]), 'Val': [-0.977278, 0.950088, -0.103219, 0.151357, 0.410599, 0.673247], 'Name': ['John', 'Robert', 'Sam', 'Tim', 'Hector', 'Melissa'] }) # ---------------------- # 强制按时间列升序排序,必须步骤 df1 = df1.sort_values('Date').reset_index(drop=True) df2 = df2.sort_values('Date').reset_index(drop=True) # 匹配df1每个时间点在df2中最近时间对应的行索引 match_res = pd.merge_asof( left=df1[['Date']], right=df2[['Date']].reset_index(names='df2_row_idx'), on='Date', direction='nearest' # 核心参数:取时间差绝对值最小的行 # 如需限制最大允许时间差,加参数即可,例:tolerance=pd.Timedelta(minutes=1) ) # 提取匹配到的df2行,得到最终结果 df3 = df2.loc[match_res['df2_row_idx']].reset_index(drop=True)
结果验证
执行print(df3)输出和期望结果完全一致:
Date Val Name 0 2015-02-24 00:00:00 -0.977278 John 1 2015-02-24 00:01:00 0.950088 Robert 2 2015-02-24 00:02:00 -0.103219 Sam 3 2015-02-24 00:04:00 0.410599 Hector 4 2015-02-24 00:04:00 0.410599 Hector 5 2015-02-24 00:05:00 0.673247 Melissa
补充说明
- 该方法是pandas原生向量化实现,即使是十万级以上的大表,匹配速度也比逐行循环/单值查询快数十倍
- 如果需要匹配时保留df1的字段,只需要调整merge_asof的左右表字段、后缀参数即可,直接合并两个表的列
- 若时间列是索引而非普通列,把
on='Date'替换成left_index=True, right_index=True即可
内容的提问来源于stack exchange,提问作者Rob Burry
相关产品推荐
相关产品推荐

