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

Pandas合并两个DataFrame 保留df1数据按同值首次出现对齐

Pandas 两表按指定规则关联实现

需求说明

  • 关联df1、df2两个DataFrame时需保留df1的全部数据,不能出现行丢失
  • df2中与df1匹配的值(即df2.C == df1.A),仅对齐到df1中该值首次出现的行,df1中后续重复出现的同值行不关联df2数据,对应关联列留空
  • 常规inner连接会丢失df1未匹配数据,普通左连接会将df1中所有同值行都与df2做笛卡尔积匹配,不符合预期

实现代码

import pandas as pd 

# 原始df1、df2定义
df1 = pd.DataFrame([
    {'A':123456, 'B':'4/1/22'},
    {'A':234567, 'B':'4/1/22'},
    {'A':345678, 'B':'4/1/22'},
    {'A':567890, 'B':'4/1/22'},
    {'A':234567, 'B':'4/3/22'},
    {'A':456789,'B':'4/4/22'}
])
df2 = pd.DataFrame([
    {'C':159357,'D':'4/1/22'},
    {'C':234567,'D':'4/1/22'},
    {'C':234567,'D':'4/3/22'},
    {'C':234567,'D':'4/2/22'},
    {'C':234567,'D':'4/3/22'},
    {'C':456789,'D':'4/1/22'},
    {'C':654852,'D':'4/7/22'},
    {'C':753951,'D':'4/1/22'}
])

# 标记df1中每个A值首次出现的行
df1['is_first'] = ~df1['A'].duplicated(keep='first')
# 拆分为首次出现行、非首次出现行两部分
first_occur_rows = df1[df1['is_first']].drop(columns='is_first')
non_first_rows = df1[~df1['is_first']].drop(columns='is_first').assign(C=None, D=None)

# 仅对首次出现的行执行左连接匹配df2数据
matched_part = first_occur_rows.merge(
    df2,
    how='left',
    left_on='A',
    right_on='C'
)

# 拼接匹配结果和非首次行,按原始索引排序还原df1的原有顺序
final_result = pd.concat([matched_part, non_first_rows]).sort_index().reset_index(drop=True)

实现逻辑说明

  • 用duplicated(keep='first')标记每个值的首次出现位置,避免重复值行参与匹配
  • 仅对首次出现的锚点行做左连接,保证df2的匹配数据全部挂在对应值第一次出现的位置
  • 非首次出现的df1行直接保留,关联列填充空值,不会丢失任何df1原有数据
  • 拼接后按原始索引排序,完全保留df1原有的行顺序,匹配到的df2多行数据会连续排列在对应锚点行的位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 11:06:33