基于小于且最近日期条件合并无公共列Pandas DataFrame的实现方法
Pandas 跨表时间最近邻匹配实现方案
实现思路
你需要的是按时间列的最近邻关联合并,Pandas 内置的pd.merge_asof函数专门用于处理这类有序键的近似匹配场景,无需自行循环匹配,性能和可读性都更好。
注意:你需求描述中提到的"匹配小于该值的最近记录"与你给出的示例结果第四行逻辑不符,示例中第四行实际匹配了大于ArrivalDateCap的最近值(全局最近),下面的代码会同时给出两种场景的实现。
完整实现代码
1. 环境和数据准备(和你提供的示例一致)
import pandas as pd # 示例数据定义 df1 = {'ID1': ['A12', 'A13', 'A14'], 'ArrivalDateTime': ["2021-09-20 16:37", "2021-09-21 03:10", "2021-09-26 03:10"]} df2 = {'ID': ['001', '002', '003','004'], 'ArrivalDateCap': ["2021-09-20 18:00", "2021-09-21 18:00", "2021-09-20 18:00","2021-09-25 16:00"]} df1 = pd.DataFrame(df1) df1["ArrivalDateTime"] = pd.to_datetime(df1["ArrivalDateTime"],format="%Y-%m-%d %H:%M") df2 = pd.DataFrame(df2) df2["ArrivalDateCap"] = pd.to_datetime(df2["ArrivalDateCap"],format="%Y-%m-%d %H:%M")
2. 执行合并
场景1:匹配全局最近的ArrivalDateTime(和你给出的示例结果完全一致)
# 1. 先对两个表的关联时间列进行升序排序(merge_asof的强制要求) df1_sorted = df1.sort_values('ArrivalDateTime').reset_index(drop=True) # 保存df2的原始索引,后续可恢复原顺序 df2_sorted = df2.sort_values('ArrivalDateCap').reset_index(names='origin_idx') # 2. 最近邻匹配 df3 = pd.merge_asof( left=df2_sorted, right=df1_sorted, left_on='ArrivalDateCap', right_on='ArrivalDateTime', direction='nearest' # 匹配最近的,不管大小 ) # 3. 恢复df2的原始顺序 df3 = df3.sort_values('origin_idx').drop('origin_idx', axis=1).reset_index(drop=True)
输出的df3和你给出的预期结果完全一致。
场景2:仅匹配小于ArrivalDateCap的最近记录(和你文字描述的需求一致)
仅需修改direction参数即可:
df3 = pd.merge_asof( left=df2_sorted, right=df1_sorted, left_on='ArrivalDateCap', right_on='ArrivalDateTime', direction='backward' # 仅匹配小于等于左表键的最近右表记录 )
如果没有符合条件的记录,对应字段会返回空值。
参数说明
direction可选值:nearest:全局最近匹配backward:仅匹配小于等于左表键的最近记录forward:仅匹配大于等于左表键的最近记录
内容的提问来源于stack exchange,提问作者Hummer
相关产品推荐
相关产品推荐

