如何筛选Python DataFrame中不同列存在相似性匹配的行
实现思路
从你给出的示例推导,需求的核心是:当某行的name或ID列和其他任意行的对应列字符串相似性达到阈值时,保留该行,无相似匹配的孤例行直接删除。以下方案采用最常用的莱文斯坦距离作为相似性判断标准,阈值可根据实际业务需求灵活调整。
依赖安装
如需使用优化后的相似度计算库,执行以下安装命令:
pip install pandas fuzzywuzzy python-Levenshtein
如果你不想安装第三方依赖,也可以用Python标准库
difflib实现相似度计算,后续代码中把fuzz.ratio(x, row[col])替换为difflib.SequenceMatcher(None, x, row[col]).ratio() * 100即可,效果一致。
完整实现代码
import pandas as pd from fuzzywuzzy import fuzz # 输入数据 df = pd.DataFrame({ 'name':['Dupont','Dupant','Darang','BA','Scatt','Sieb'], 'ID': ['789985','789852','9852220','015220','015221','10022'] }) # 配置相似性阈值,取值范围0-100,数值越高对相似性的要求越严格 SIMILAR_THRESHOLD = 80 def has_similar_row(row, df, check_cols=['name', 'ID']): for col in check_cols: # 计算当前行对应列和所有其他行同列的相似度 sim_list = df[col].apply(lambda x: fuzz.ratio(x, row[col])) # 排除自身比对结果,存在任意一个其他行相似度达标就返回True if any(sim_list.drop(row.name) >= SIMILAR_THRESHOLD): return True return False # 筛选符合要求的行 result_df = df[df.apply(lambda x: has_similar_row(x, df), axis=1)].reset_index(drop=True) print(result_df)
运行输出
name ID 0 Dupont 789985 1 Dupant 789852 2 BA 015220 3 Scatt 015221
和你给出的预期结果完全匹配。
可调优方向
- 可针对不同列设置独立的相似性阈值,适配
name和ID不同的相似判断规则 - 如果ID仅需要前缀匹配,可将相似度计算逻辑替换为前缀校验,比如判断两个ID前N位是否相同,匹配效率更高
- 数据量较大时,可先按列做前缀分桶预筛选,再计算相似度,避免全量两两比对的性能损耗
内容的提问来源于stack exchange,提问作者SANDWIDI
相关产品推荐
相关产品推荐

