Python实现带字段权重的模糊字符串匹配完成Salesforce记录去重
Python实现带字段权重的Salesforce记录模糊去重方案
核心选型
优先选择基于C扩展的高效相似度计算库rapidfuzz配合pandas做数据处理,避免使用纯Python实现的编辑距离算法,整体性能比fuzzywuzzy+自定义循环的方案高10~100倍,足以应对绝大多数场景的记录去重需求。
实现逻辑
- 先定义字段权重字典,总权重自动取字典值的和,无需手动维护
- 单个字段的相似度先做归一化处理,映射到0~1区间后乘以对应字段权重
- 所有字段加权得分求和后除以总权重,得到最终0~1区间的总相似度
- 提前设置相似度阈值,得分超过阈值的记录对判定为重复
性能优化建议
- 万条以下的小数据量可以直接用笛卡尔积生成待比对记录对,记得过滤掉
id_a >= id_b的配对,避免同一条记录和自己比对、同一对记录重复比对 - 数据量超过1万条时,先做分桶裁剪:比如先按Email的前缀/域名、姓氏首字母等特征做分桶,仅比对同桶内的记录,可大幅降低无效计算量
- 不要用pandas的逐行apply计算相似度,可改用rapidfuzz的process模块批量计算,或者用numpy向量化操作,性能提升更明显
示例代码
import pandas as pd from rapidfuzz import fuzz # 1. 导入待去重数据集 df = pd.DataFrame({ "名字": ["Matt", "Alex", "Matthew"], "姓氏": ["Metro", "Two", "Meos"], "Email": ["name@example.com", "Three", "name@example.com"] }) df = df.fillna('') # 空值填充为空字符串,避免计算错误 # 2. 配置字段权重 field_weights = {"名字": 10, "姓氏": 10, "Email": 30} total_weight = sum(field_weights.values()) repeat_threshold = 0.7 # 自定义重复判定阈值 # 3. 生成待比对记录对(小数据量场景) df["record_id"] = df.index compare_pairs = df.merge(df, how="cross", suffixes=("_left", "_right")) compare_pairs = compare_pairs[compare_pairs["record_id_left"] < compare_pairs["record_id_right"]] # 4. 计算加权总相似度 for field in field_weights: compare_pairs[f"{field}_score"] = compare_pairs.apply( lambda x: fuzz.ratio(x[f"{field}_left"], x[f"{field}_right"]) / 100 * field_weights[field], axis=1 ) compare_pairs["total_similarity"] = compare_pairs[[f"{f}_score" for f in field_weights]].sum(axis=1) / total_weight # 5. 筛选重复记录对 duplicates = compare_pairs[compare_pairs["total_similarity"] >= repeat_threshold]
内容的提问来源于stack exchange,提问作者Matthew Metros
相关产品推荐
相关产品推荐

