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

如何按规则删除Pandas DataFrame中的非精确重复记录?

Pandas非精确重复数据清洗实现

问题场景

我们有如下Pandas DataFrame:

IndexFirstNameSurnameAdressSource
1PaulBagginssamegood
2PaaulBagginssamebad
3MaryBagginssamegood
4MaryBagginssamebad
5LucySmithotherbad

需要完成的清洗目标:

  • 先筛选出住址(Adress)相同的记录(Adress作为家庭唯一标识)
  • 删除因数据源不同导致FirstName输入错误的潜在重复项(即索引2、4的记录)

已尝试方法局限

用df.drop_duplicates(subset=['FirstName','Surname', 'Adress'], keep='first')只能删除索引4这种精确重复的记录,处理不了像索引2中Paul和Paaul这种非精确的重复。

已经实现了基于difflib的文本相似度计算函数:

from difflib import SequenceMatcher

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

比如similar('Paul', 'Paaul')返回0.888,但不知道怎么把这个逻辑整合到去重流程里。

期望实现流程

先生成包含Similar_to_Index(匹配到的目标索引)和Ratio(相似度)列的中间DataFrame,再按照**相似度Ratio>0.8且Source为'bad'**的规则删除索引2、4,最终得到两个结果:

  1. 清洗后的DataFrame
  2. 被删除记录的DataFrame

具体实现代码

步骤1:导入依赖并初始化数据

import pandas as pd
from difflib import SequenceMatcher

# 初始化示例DataFrame
data = {
    'Index': [1,2,3,4,5],
    'FirstName': ['Paul', 'Paaul', 'Mary', 'Mary', 'Lucy'],
    'Surname': ['Baggins', 'Baggins', 'Baggins', 'Baggins', 'Smith'],
    'Adress': ['same', 'same', 'same', 'same', 'other'],
    'Source': ['good', 'bad', 'good', 'bad', 'bad']
}
df = pd.DataFrame(data).set_index('Index')

# 相似度计算函数
def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

步骤2:生成中间匹配结果

按Adress和Surname分组,在每组内计算每条记录与同组其他记录的相似度,找到最匹配的记录索引和对应相似度:

# 初始化新增列
df['Similar_to_Index'] = None
df['Ratio'] = 0.0

# 按家庭标识分组处理
for (adress, surname), group in df.groupby(['Adress', 'Surname']):
    # 遍历组内每条记录
    for idx, row in group.iterrows():
        # 排除自身,计算与组内其他记录的相似度
        others = group.drop(idx)
        if not others.empty:
            # 计算当前记录与其他记录的FirstName相似度
            others['current_ratio'] = others['FirstName'].apply(lambda x: similar(row['FirstName'], x))
            # 找到相似度最高的记录
            max_row = others.loc[others['current_ratio'].idxmax()]
            df.loc[idx, 'Similar_to_Index'] = max_row.name
            df.loc[idx, 'Ratio'] = max_row['current_ratio']

此时中间DataFrame结果如下:

IndexFirstNameSurnameAdressSourceSimilar_to_IndexRatio
1PaulBagginssamegood20.888...
2PaaulBagginssamebad10.888...
3MaryBagginssamegood41.0
4MaryBagginssamebad31.0
5LucySmithotherbadNone0.0

步骤3:筛选并分离待删除记录

根据规则筛选出要删除的记录,同时保留清洗后的数据集:

# 筛选待删除条件:相似度>0.8 且 Source为'bad'
to_drop = df[(df['Ratio'] > 0.8) & (df['Source'] == 'bad')]
# 清洗后的数据集:排除待删除记录
cleaned_df = df.drop(to_drop.index)

# 重置索引(可选,根据需求调整)
cleaned_df = cleaned_df.reset_index(drop=False)
to_drop = to_drop.reset_index(drop=False)

最终结果

  • 清洗后的DataFrame:
IndexFirstNameSurnameAdressSourceSimilar_to_IndexRatio
01PaulBagginssamegood2
13MaryBagginssamegood4
25LucySmithotherbadNone
  • 被删除的记录DataFrame:
IndexFirstNameSurnameAdressSourceSimilar_to_IndexRatio
02PaaulBagginssamebad1
14MaryBagginssamebad3

补充说明

  • 如果组内存在多条高相似度记录,可以根据实际需求调整匹配逻辑(比如优先保留Source='good'的记录作为匹配基准)
  • 相似度阈值(0.8)可以根据业务场景灵活调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:35