You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于两个DataFrame不同日期列的日期条件合并数据

问题背景

现有两个DataFrame,结构如下:

df1结构

包含P_CLIENT_ID(用户ID)、P_DATE_ENCOUNTER(就诊日期)两列,示例数据:

P_CLIENT_IDP_DATE_ENCOUNTER
258352016-12-21
258352017-02-21
258352017-04-25
258352017-06-21
258352017-09-04
258352018-01-08
258352018-04-03

df2结构

包含R_CLIENT_ID(用户ID)、R_DATE_TESTED(检测日期)、R_RESULT(检测结果)三列,示例数据:

R_CLIENT_IDR_DATE_TESTEDR_RESULT
258352017-03-0720.0
258352017-08-0320.0
258352018-03-2320.0
258352019-06-2820.0
258352019-08-1942.0
258352020-04-2040.0
258352021-06-0320.0

合并规则

将df2合并到主表df1上,关联键为用户ID,追加匹配到的最新检测记录,规则如下:

  • 仅匹配检测日期早于就诊日期的记录,取最近的一条
  • 没有符合条件的检测记录时,检测相关字段置空
    预期结果如下:
P_CLIENT_IDR_CLIENT_IDP_DATE_ENCOUNTERR_DATE_TESTEDR_RESULT
2583525835.02016-12-21NaNNaN
2583525835.02017-02-21NaNNaN
2583525835.02017-04-252017-03-0720.0
2583525835.02017-06-212017-03-0720.0
2583525835.02017-09-042017-08-0320.0
2583525835.02018-01-082017-08-0320.0
2583525835.02018-04-032018-03-2320.0

数据规模

实际数据集df1约70万行,df2约12.5万行。

解决方案

你当前全量merge后去重的方案存在结果不准、性能差的问题,推荐使用专门处理时间邻近匹配的merge_asof方法,逻辑完全匹配需求且运行效率极高:

import pandas as pd
import numpy as np

# 示例数据构造(已修正原代码df1列名笔误P_CLIENT_D为P_CLIENT_ID)
df1 = pd.DataFrame({
    'P_CLIENT_ID': ['25835','25835','25835','25835','25835','25835','25835'],
    'P_DATE_ENCOUNTER': ['2016-12-21','2017-02-21','2017-04-25','2017-06-21','2017-09-04','2018-01-08','2018-04-03']
})
df2 = pd.DataFrame({
    'R_CLIENT_ID': ['25835','25835','25835','25835','25835','25835','25835'],
    'R_DATE_TESTED': ['2017-03-07','2017-08-03','2018-03-23','2019-06-28','2019-08-19','2020-04-20','2021-06-03'],
    'R_RESULT':[20,20,20,20,42,40,20]
})

# 1. 将日期列转为datetime类型,是merge_asof的必要前提
df1['P_DATE_ENCOUNTER'] = pd.to_datetime(df1['P_DATE_ENCOUNTER'])
df2['R_DATE_TESTED'] = pd.to_datetime(df2['R_DATE_TESTED'])

# 2. 按用户ID和日期排序,merge_asof要求两个表的匹配日期列有序
df1 = df1.sort_values(by=['P_CLIENT_ID', 'P_DATE_ENCOUNTER']).reset_index(drop=True)
df2 = df2.sort_values(by=['R_CLIENT_ID', 'R_DATE_TESTED']).reset_index(drop=True)

# 3. 执行asof合并,按用户分组匹配小于就诊日期的最近检测记录
df_merged = pd.merge_asof(
    df1, 
    df2,
    left_on='P_DATE_ENCOUNTER',
    right_on='R_DATE_TESTED',
    left_by='P_CLIENT_ID',
    right_by='R_CLIENT_ID',
    direction='backward'
)

运行上述代码得到的结果完全符合预期,处理你提到的100万级以内数据仅需几秒,不会产生笛卡尔积中间表,内存占用极低。


内容的提问来源于stack exchange,提问作者Mazil_tov998

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:48:03