0

0

如何基于公共标识列合并两个 DataFrame 并优先保留第二张表的重复行

碧海醫心

碧海醫心

发布时间:2026-01-07 17:20:03

|

497人浏览过

|

来源于php中文网

原创

如何基于公共标识列合并两个 DataFrame 并优先保留第二张表的重复行

本文介绍一种高效、可扩展的方法,使用 pd.concat() 配合布尔索引实现两表按指定列(支持单列或多列)合并:保留 df2 的全部行,仅补充 df1 中在 df2 中完全不存在的行(含重复),避免 combine_first 导致的重复膨胀问题。

在 Pandas 数据处理中,当需要“以 df2 为主、df1 为辅”合并两个结构相同的数据框(即:保留 df2 的所有行,同时只追加 df1 中在 df2 中完全未出现过的记录(包括重复行)),直接使用 combine_first 或 merge 往往会因索引对齐逻辑导致重复行被错误广播——正如示例中 A=123 的行从 df2 的 4 行 + df1 的 2 行,意外膨胀为 8 行。

正确解法是:显式分离“覆盖部分”与“补充部分”,再垂直拼接:

✅ 推荐方案:concat + 布尔索引(高效、清晰、支持多列)

import pandas as pd
from io import StringIO

# 示例数据
csv1_data = """A,B,C,D
123,xyz,S1,1111
123,xyz,S1,1111
234,mno,S3,2222
999,abc,S9,9999
999,abc,S9,9999"""

csv2_data = """A,B,C,D
123,abc,S1,1234
123,abc,S1,1234
123,abc,S1,1234
123,cde,S2,2345
234,nop,S3,
567,pqr,S5,5555"""

df1 = pd.read_csv(StringIO(csv1_data), dtype=str, keep_default_na=False)
df2 = pd.read_csv(StringIO(csv2_data), dtype=str, keep_default_na=False)

# ✅ 核心逻辑:取 df2 全部 + df1 中 A 值不在 df2.A 中的行(保留原始重复)
key_col = 'A'
result = pd.concat([
    df2,
    df1[~df1[key_col].isin(df2[key_col])]
], ignore_index=True)

print(result)

输出:

Hitems
Hitems

HITEMS是一个AI驱动的创意设计平台,支持一键生成产品

下载
     A    B   C     D
0  123  abc  S1  1234
1  123  abc  S1  1234
2  123  abc  S1  1234
3  123  cde  S2  2345
4  234  nop  S3      
5  567  pqr  S5  5555
6  999  abc  S9  9999
7  999  abc  S9  9999

? 支持多列联合标识(动态适配)

当关键标识不止一列(如 ['A', 'B'] 或 ['A', 'A1', 'A2']),只需将列名列表传入,并利用 MultiIndex.isin() 进行精确匹配:

key_cols = ['A']  # 可动态替换为 ['A', 'B']、['A', 'A1', 'A2'] 等
# 构建 MultiIndex 进行成员判断
df1_mask = ~df1.set_index(key_cols).index.isin(df2.set_index(key_cols).index)
result = pd.concat([df2, df1[df1_mask]], ignore_index=True)
? 性能提示:该方法时间复杂度为 O(n + m),远优于基于索引重排的 combine_first(易触发内部广播),特别适合百万级数据场景。

⚠️ 注意事项与最佳实践

  • 不要用 set_index 后 combine_first:它会将 df1 中每个匹配索引的所有行与 df2 中对应索引的所有行做笛卡尔式填充,导致重复爆炸;
  • isin 判断基于值而非位置:确保 key 列类型一致(如都为字符串),避免因 int/str 混合导致匹配失败;
  • 空值(NaN)需预处理:isin() 对 NaN 默认返回 False,若业务允许 NaN 作为有效键,建议先用 fillna() 统一占位符(如 "");
  • 内存友好:全程不修改原 DataFrame,无需 .copy(),ignore_index=True 保证结果索引连续。

综上,pd.concat([df2, df1[~df1[key].isin(df2[key])]]) 是解决“主从式去重合并”的简洁、健壮且高性能的标准范式,兼顾可读性与工程可维护性。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1462

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

612

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

547

2024.03.22

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

6

2026.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号