如何去除DataFrame中A&C匹配、B&C非精确匹配的重复项
移除DataFrame中两类重复行的实现方法
需求说明
需要移除DataFrame中的两类重复行:
- 第一类:A列与C列值完全匹配的重复行
- 第二类:B列(姓名)与C列值匹配的重复行,其中B列存在以下特殊情况:
- 包含空值,空值行需保留
- 姓名存在非精确匹配:部分行仅含姓+名,部分包含姓+名+中间名+学位,只要姓和名一致即视为重复
- 重复行可保留任意一行,无需固定保留某条
初始DataFrame
import pandas as pd d = {'A': [123498, 123498, 234875, 457898, 'SMITHJ', 'DOEJ'], 'B': ['SIMON, PAUL JD', None, 'DOE, JANE MARY PHD', 'MERCURY, FREDRICK MS', None, 'DOE, JANE'], 'C': ['red', 'red', 'green', 'red', 'blue', 'green']} df = pd.DataFrame(data=d)
输出结果:
A B C 0 123498 SIMON, PAUL JD red 1 123498 None red 2 234875 DOE, JANE MARY PHD green 3 457898 MERCURY, FREDRICK MS red 4 SMITHJ None blue 5 DOEJ DOE, JANE green
期望结果
A B C 0 123498 SIMON, PAUL JD red 3 457898 MERCURY, FREDRICK MS red 4 SMITHJ None blue 5 DOEJ DOE, JANE green
解决方案步骤
1. 处理A列与C列的精确重复
直接使用drop_duplicates方法,指定重复判断的列为A和C,保留任意一行(示例中选keep='first',改为keep='last'也符合要求):
df_clean = df.drop_duplicates(subset=['A', 'C'], keep='first').copy()
2. 处理B列与C列的非精确重复
首先清洗B列,提取姓名的核心部分(仅保留姓+名),再基于核心姓名与C列的组合去重:
# 定义函数提取核心姓名:拆分姓与名,忽略中间名和学位 def extract_core_name(name): if pd.isna(name): return name last_name, rest = name.split(',', 1) first_name = rest.strip().split()[0] return f"{last_name}, {first_name}" # 生成核心姓名辅助列 df_clean['core_B'] = df_clean['B'].apply(extract_core_name) # 筛选保留行:空值行直接保留;非空行仅保留core_B+C组合唯一的行 mask = df_clean['core_B'].isna() | ~df_clean.duplicated(subset=['core_B', 'C'], keep='first') df_final = df_clean[mask].drop(columns='core_B')
运行上述代码后,df_final即为符合要求的结果。若需要保留另一组重复行(如索引1、2),只需将keep='first'改为keep='last'即可。
内容的提问来源于stack exchange,提问作者be84
相关产品推荐
相关产品推荐

