基于ID与日期匹配DataFrame,添加最近事件日期列的实现方案
解决方案
步骤说明
- 先将两个DataFrame的日期列转换为
datetime类型,确保能正确进行日期比较。 - 对
Events按ID和Event_Date排序,这是使用merge_asof的前提条件。 - 使用
pandas.merge_asof()函数,按ID匹配样本与事件,同时筛选出早于对应Sample_Date的最近Event_Date。 - 整理结果,保留需要的列即可得到目标输出。
代码实现
import pandas as pd # 构造示例数据 samples = pd.DataFrame({ 'ID': [500001, 500002, 500003], 'Sample_Date': ['2021-09-28', '2021-09-29', '2021-10-15'] }) events = pd.DataFrame({ 'ID': [500001, 500001, 500003], 'Event_Date': ['2021-09-20', '2021-10-05', '2021-10-09'], 'Event': ['BN', 'BN', 'AS'] }) # 转换日期列为datetime类型 samples['Sample_Date'] = pd.to_datetime(samples['Sample_Date']) events['Event_Date'] = pd.to_datetime(events['Event_Date']) # 对Events按ID和Event_Date排序 events_sorted = events.sort_values(by=['ID', 'Event_Date']) # 使用merge_asof匹配最近的早于Sample_Date的Event_Date result = pd.merge_asof( samples.sort_values(by=['ID', 'Sample_Date']), # 样本也需要按ID和日期排序 events_sorted, on='Sample_Date', # 用于比较的日期列 by='ID', # 分组匹配的键 direction='backward' # 找小于等于Sample_Date的最近日期 ) # 整理结果,重命名列并保留需要的字段 result = result.rename(columns={'Event_Date': 'last_Event_to_sample'}) result = result[['ID', 'Sample_Date', 'last_Event_to_sample']].sort_index() print(result)
输出结果
ID Sample_Date last_Event_to_sample 0 500001 2021-09-28 2021-09-20 1 500002 2021-09-29 NaT 2 500003 2021-10-15 2021-10-09
补充说明
merge_asof的direction='backward'参数会为每个样本找到小于等于Sample_Date的最近Event_Date,完全符合需求。- 如果某个ID没有符合条件的事件(如500002),对应列会显示
NaT(datetime类型的空值),可以用fillna()转成NaN或其他自定义值。 - 这种方法比逐行遍历(如
apply)效率高得多,适合处理大规模数据。
内容的提问来源于stack exchange,提问作者Marco Mikuš
相关产品推荐
相关产品推荐

