影刀RPA 数据去重的七种方法:从简单到复杂的选型 影刀RPA 数据去重的七种方法从简单到复杂的选型作者林焱什么情况用这个你从三个平台采集了商品数据合并后发现有重复。Excel里的订单记录导入了两次客户名单里有同名同姓不同人、也有同一人多条记录。数据去重听起来简单——不就drop_duplicates()嘛实际远不止。不同场景需要不同的去重策略有时候全字段相同才是重复有时候只要ID相同就算重复有时候要保留第一条有时候要合并两条记录的信息。这篇文章从简单到复杂把七种去重方法的使用场景和选择逻辑讲清楚。怎么做方法一集合去重最简单适合单列数据、全字段重复的场景。# 字符串列表去重names[张三,李四,张三,王五,李四]unique_nameslist(set(names))print(unique_names)# [张三, 李四, 王五]顺序不保证# 保持原顺序的去重seenset()unique_ordered[]fornameinnames:ifnamenotinseen:seen.add(name)unique_ordered.append(name)print(unique_ordered)# [张三, 李四, 王五]方法二字典键去重按关键字段适合多个字段中只有某个字段决定是否重复如ID。records[{id:001,name:商品A,price:99},{id:002,name:商品B,price:199},{id:001,name:商品A(新),price:109},# 同ID信息更新了]# 按ID去重保留第一次出现的seen{}forrecordinrecords:keyrecord[id][video(video-owL94VaT-1784132827886)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限)]ifkeynotinseen:seen[key]record unique_recordslist(seen.values())# 如果需要保留最后出现的更新的数据forrecordinrecords:seen[record[id]]record# 直接覆盖方法三多字段组合键去重适合需要多个字段组合才能判断重复。# 按姓名手机号组合去重contacts[{name:张三,phone:13800138000,email:ax.com},{name:张三,phone:13900139000,email:bx.com},# 同名人不同手机{name:张三,phone:13800138000,email:cx.com},# 重复同名同手机]defdedup_by_keys(records,keys):按多个字段组合去重seenset()result[]forrecordinrecords:![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/10e4b6436b9549cdb438f8a1836d159b.png#pic_center)# 生成组合键composite_keytuple(record.get(k,)forkinkeys)ifcomposite_keynotinseen:seen.add(composite_key)result.append(record)returnresult uniquededup_by_keys(contacts,[name,phone])# 结果张三138... 和 张三139... 两条方法四模糊匹配去重适合文本不完全一样但基本是同一内容的场景。importdifflibdeffuzzy_dedup(strings,threshold0.85):模糊去重——相似度超过阈值的视为重复unique[]forsinstrings:is_dupFalseforexistinginunique:similaritydifflib.SequenceMatcher(None,s,existing).ratio()ifsimilaritythreshold:is_dupTruebreakifnotis_dup:unique.append(s)returnunique# 示例公司名稍有不同的记录names[深圳市腾讯计算机系统有限公司,深圳腾讯计算机系统有限公司,# 少了市深圳市腾讯科技公司,# 不同]unique_namesfuzzy_dedup(names,threshold0.8)print(unique_names)# 前两条会去重注意模糊匹配去重计算量大数据量1000条时建议先做精确去重缩小范围。方法五合并去重取并集适合两条重复记录互补的信息要合并。defmerge_duplicates(records,key_field):合并重复记录——取所有字段的非空并集merged{}forrecordinrecords:keyrecord[key_field]ifkeynotinmerged:merged[key]record.copy()else:# 合并非空字段existingmerged[key]forfield,valueinrecord.items():ifvalueandnotexisting.get(field):existing[field]value# 用新值填充空字段returnlist(merged.values())# 示例records[{id:001,name:张三,phone:13800138000,email:},{id:002,name:李四,phone:,email:lisiqq.com},{id:001,name:张三,phone:,email:zhangsanqq.com},]mergedmerge_duplicates(records,id)# 结果张三的信息现在有完整的phone和email方法六时间优先去重适合同一ID有多条历史记录保留最新的。fromdatetimeimportdatetimedefkeep_latest(records,key_field,time_field):按关键字段去重保留时间最新的latest{}forrecordinrecords:keyrecord[key_field]record_timerecord.get(time_field)# 解析时间ifisinstance(record_time,str):try:record_timedatetime.strptime(record_time,%Y-%m-%d %H:%M:%S)except:record_timedatetime.minifkeynotinlatest:latest[key]recordelse:existing_timelatest[key].get(time_field)ifisinstance(existing_time,str):try:existing_timedatetime.strptime(existing_time,%Y-%m-%d %H:%M:%S)except:existing_timedatetime.minifrecord_timeexisting_time:latest[key]recordreturnlist(latest.values())方法七权重优先去重适合多源数据去重不同来源的可信度不同。defkeep_highest_quality(records,key_field,source_weights): 按来源权重去重——保留可信度最高的 source_weights: {官方数据库: 10, 用户提交: 3, 公开采集: 1} best{}forrecordinrecords:keyrecord[key_field]sourcerecord.get(source,未知)weightsource_weights.get(source,0)ifkeynotinbest:best[key](weight,record)else:existing_weight,_best[key]ifweightexisting_weight:best[key](weight,record)return[recordfor_,recordinbest.values()]有什么坑坑一set去重后顺序乱了现象用set()去重后列表顺序和原来不一样了Python 3.7的dict保持插入顺序但set不保证。解决保持顺序用dict.fromkeys()unique_orderedlist(dict.fromkeys(items))坑二忽略了None和空字符串的区别现象None和被判定为不同的key导致没去掉重复。解决生成组合键时统一规范化空值temu店群自动化报活动案例defnormalize_key(value):规范化键值——把各种空值统一ifvalueisNoneorstr(value).strip():return_EMPTY_returnstr(value).strip()坑三模糊去重在大数据集上超慢现象5000条数据做两两模糊比较O(n²)复杂度流程卡死。解决先精确去重再按首字母或拼音分组缩小候选范围。或者用距离算法先聚类。坑四去重决策没有记录现象去重后不知道删了什么出了问题没法回溯。解决记录去重日志defdedup_with_log(records,key_func):带去重日志seen{}duplicates[]forrecordinrecords:keykey_func(record)ifkeyinseen:duplicates.append({kept:seen[key],removed:record})else:seen[key]recordprint(f去重:{len(records)}→{len(seen)}条, 移除{len(duplicates)}条重复)returnlist(seen.values()),duplicates坑五业务上的重复和技术上的重复不一致现象程序认为商品ID不同就不是重复但业务上同一个商品在不同平台有不同ID。解决这种情况需要建立商品映射表——先做技术去重按字段再做业务匹配按规则两者分开处理。总结去重方法的选择顺序——先用集合/dict按关键字段精确去重最快再根据业务需求选择保留策略第一条、最新、合并、权重最后才考虑模糊匹配最慢。大部分场景用方法一、二、三就够了。每做一次去重把去重原因和数量记到日志里。