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

如何按最近且不晚于目标日期的条件合并两个Pandas DataFrame

解决按ID和最近日期左外连接DataFrame的问题

你使用pd.merge_asof未得到正确结果,核心原因是未将日期列转为datetime类型,或未按要求对两个DataFrame排序。merge_asof有严格的前置要求:左右DataFrame必须先按by列分组,再按日期列排序,且日期列需为datetime格式,否则匹配逻辑会失效。

完整解决方案代码

import pandas as pd

# 构造示例数据
df_1 = pd.DataFrame({
    'col_1': [1, 2, 3, 4],
    'date_1': ['2023-1-1', '2023-1-2', '2023-1-3', '2023-1-4'],
    'id': [1, 1, 2, 3]
})

df_2 = pd.DataFrame({
    'col_2': [5, 6, 7, 8],
    'date_2': ['2023-1-1', '2023-1-1', '2023-1-4', '2023-1-9'],
    'id': [1, 2, 1, 3]
})

# 1. 将日期列转换为datetime类型(merge_asof要求的格式)
df_1['date_1'] = pd.to_datetime(df_1['date_1'])
df_2['date_2'] = pd.to_datetime(df_2['date_2'])

# 2. 按id和日期列排序(merge_asof的强制要求:先分组再按日期排序)
df_1 = df_1.sort_values(['id', 'date_1'])
df_2 = df_2.sort_values(['id', 'date_2'])

# 3. 执行merge_asof左外连接
result = pd.merge_asof(
    df_1,
    df_2,
    by='id',  # 按id匹配
    left_on='date_1',
    right_on='date_2',
    direction='backward',  # 找<=date_1的最近date_2记录
    allow_exact_matches=True  # 允许精确匹配(默认开启)
)

# 可选:将日期列转回字符串格式(匹配预期输出的显示格式)
result['date_1'] = result['date_1'].dt.strftime('%Y-%m-%d')
result['date_2'] = result['date_2'].dt.strftime('%Y-%m-%d').where(pd.notnull(result['date_2']), None)

print(result)

输出结果

执行后会得到符合预期的左外连接结果:

col_1    date_1  id  col_2    date_2
0      1  2023-01-01   1    5.0  2023-01-01
1      2  2023-01-02   1    5.0  2023-01-01
2      3  2023-01-03   2    6.0  2023-01-01
3      4  2023-01-04   3    NaN      None

关键参数说明

  • by='id':限定仅匹配同id的行,满足第一个连接条件
  • direction='backward':在date_2 <= date_1的范围内,选择与date_1间隔最小的记录,满足第二、第三个连接条件
  • 左外连接是merge_asof的默认行为,自动保留左表(df_1)的所有行,无匹配项则填充NaN/None

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:52:48