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

如何基于条件合并两个DataFrame并匹配对应id

实现方法

先构造示例数据方便复现:

import pandas as pd

# 构造df1
df1 = pd.DataFrame({
    'name': ['name_1', 'name_2', 'name_3', 'name_1'],
    'year': [2018, 2017, 2021, 2022]
})

# 构造df2
df2 = pd.DataFrame({
    'name': ['name_1', 'name_2', 'name_1'],
    'start': [2017, 2017, 2022],
    'end': [2021, 2022, 2023],
    'id': [1, 2, 3]
})

方法一:先合并再过滤(适合小数据集)

先通过name字段做全连接,再筛选year落在[start, end)区间的记录,最后保留目标列:

# 按name合并两个DataFrame
merged = pd.merge(df1, df2, on='name', how='left')
# 过滤符合年份区间的记录
result = merged[(merged['year'] >= merged['start']) & (merged['year'] < merged['end'])]
# 保留原df1的列和匹配到的id
result = result[['name', 'year', 'id']]

执行后结果:

nameyearid
name_120181
name_220172
name_120223

注:无匹配区间的记录会被过滤,若需保留所有df1行并将无匹配的id设为NaN,可后续和原df1做左连接。

方法二:用merge_asof高效匹配(适合大数据集)

Pandas的merge_asof专为有序键的区间左连接设计,不会产生笛卡尔积,性能远优于全连接后过滤:

# 对两个DataFrame按name和年份类字段排序(merge_asof要求键有序)
df1_sorted = df1.sort_values(['name', 'year'])
df2_sorted = df2.sort_values(['name', 'start'])

# 执行区间匹配
result = pd.merge_asof(
    df1_sorted,
    df2_sorted,
    by='name',  # 按name分组匹配
    left_on='year',
    right_on='start',
    direction='backward',  # 匹配小于等于year的最大start值
    allow_exact_matches=True
)
# 过滤掉year >= end的记录(满足year < end的条件)
result = result[result['year'] < result['end']]
# 恢复原df1的行顺序并保留目标列
result = result[['name', 'year', 'id']].sort_index()

若需保留df1所有行(无匹配时id为NaN),可执行:

final_result = df1.merge(result[['name', 'year', 'id']], on=['name', 'year'], how='left')

最终结果:

nameyearid
name_120181
name_220172
name_32021NaN
name_120223

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:28:22