影刀RPA 数据去重策略:多维度去重

影刀RPA 数据去重策略:多维度去重

影刀RPA 数据去重策略:多维度去重

作者:林焱

什么情况用什么

采集数据时有重复——同一个商品被采集了两次、同一条订单在合并时重复了、联系人有多个版本需要合并去重。简单的drop_duplicates()只能处理完全相同的行,但实际场景中需要按部分列去重、保留最新记录、合并不同字段的信息。

适用场景:采集数据去重、多源数据合并去重、联系人信息合并、订单数据去重、日志去重。

怎么做

基础去重

拼多多店群自动化上架方案

importpandasaspd df=pd.read_excel(r"C:\Data\raw_data.xlsx")# 1. 完全相同的行去重(保留第一条)df_unique=df.drop_duplicates()# 2. 按指定列去重df_unique=df.drop_duplicates(subset=['订单ID'])# 3. 保留最后一条(如果有更新)df_unique=df.drop_duplicates(subset=['订单ID'],keep='last')# 4. 去重后保留所有重复行(用于检查)duplicates=df[df.duplicated(subset=['订单ID'],keep=False)]duplicates.to_excel(r"C:\Data\duplicates_check.xlsx",index=False)

按业务规则去重

defdeduplicate_by_rule(df,key_col,sort_col=None,keep='last'):""" 按业务规则去重 key_col: 去重依据列 sort_col: 排序列(保留最新/最大的) keep: 'first'或'last' """ifsort_col:# 先按时间排序,再去重保留最新df=df.sort_values(sort_col,ascending=False)df_unique=df.drop_duplicates(subset=key_col,keep=keep)returndf_unique.reset_index(drop=True)![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e07606f62f344c288b2167b1a8a74c22.png#pic_center)# 使用:按订单ID去重,保留更新时间最新的df_clean=deduplicate_by_rule(df,key_col='订单ID',sort_col='更新时间',keep='first'# 排序后第一条就是最新的)print(f"去重前:{len(df)}行 → 去重后:{len(df_clean)}行")print(f"删除:{len(df)-len(df_clean)}条重复")

多字段去重

# 按"姓名+手机号"组合去重df_unique=df.drop_duplicates(subset=['姓名','手机号'])# 按"姓名+手机号+邮箱"三字段组合去重df_unique=df.drop_duplicates(subset=['姓名','手机号','邮箱'])# 模糊匹配去重:手机号格式不一但同一个人defnormalize_for_dedup(df,columns):"""标准化字段用于去重"""forcolincolumns:ifcol=='手机号':df[f'{col}_std']=df[col].astype(str).str.replace(r'[^0-9]','',regex=True)elifcol=='邮箱':df[f'{col}_std']=df[col].astype(str).str.lower().str.strip()elifcol=='姓名':df[f'{col}_std']=df[col].astype(str).str.strip().str.replace(' ','')std_cols=[f'{col}_std'forcolincolumns]df_unique=df.drop_duplicates(subset=std_cols)df_unique=df_unique.drop(columns=std_cols)returndf_unique# 使用df_clean=normalize_for_dedup(df,['姓名','手机号','邮箱'])

合并去重(保留不同字段的信息)

defmerge_duplicates(df,key_col,merge_cols=None):""" 合并重复记录的不同字段信息 如:记录A有手机号无邮箱,记录B有邮箱无手机号,合并后两者都有 """ifmerge_colsisNone:merge_cols=[cforcindf.columnsifc!=key_col]merged_rows=[]forkey_val,groupindf.groupby(key_col):iflen(group)==1:merged_rows.append(group.iloc[0])else:# 合并多条记录![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/9c30e64f45c94b0d8a3d43a064974a00.png#pic_center)merged={key_col:key_val}forcolinmerge_cols:# 取第一个非空值non_null=group[col].dropna()non_null=non_null[non_null!='']merged[col]=non_null.iloc[0]iflen(non_null)>0elseNonemerged_rows.append(merged)returnpd.DataFrame(merged_rows)# 使用df_merged=merge_duplicates(df,key_col='客户ID',merge_cols=['姓名','手机号','邮箱','地址'])

去重报告

defgenerate_dedup_report(df,key_col,output_path):"""生成去重报告"""total=len(df)unique=df[key_col].nunique()duplicates=total-unique report=[]report.append("数据去重报告")report.append("="*50)report.append(f"\n总记录数:{total}")report.append(f"唯一{key_col}数:{unique}")report.append(f"重复记录数:{duplicates}")report.append(f"重复率:{duplicates/total*100:.2f}%")# 列出重复的记录dup_records=df[df.duplicated(subset=key_col,keep=False)]iflen(dup_records)>0:report.append(f"\n重复记录明细(共{len(dup_records)}条):")dup_counts=dup_records.groupby(key_col).size().sort_values(ascending=False)report.append(f" 重复次数最多的前10个{key_col}:")forkey,countindup_counts.head(10).items():report.append(f"{key}: 重复{count}次")withopen(output_path.replace('.xlsx','_report.txt'),'w',encoding='utf-8')asf:f.write('\n'.join(report))returnreport# 使用generate_dedup_report(df,'订单ID',r"C:\Data\dedup_result.xlsx")

影刀RPA去重流程

【读取Excel文件】→ 原始数据 【执行Python代码】→ 检查重复 打印重复数量和重复率 【执行Python代码】→ 去重 按订单ID去重,保留更新时间最新的 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e82cb2a2c1a14a0fa3a436747071cd47.png#pic_center) 【执行Python代码】→ 生成去重报告 【写入Excel文件】→ 去重后数据 + 重复记录明细

有什么坑

坑1:drop_duplicates修改了原数据

TEMU店群如何管理运营?

# 问题:drop_duplicates默认返回新DataFrame,不改原数据df.drop_duplicates()# df没有变化!# 正确:df=df.drop_duplicates()![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8dd90c56a0db4970a2f956d6ddd60801.png#pic_center)# 或df.drop_duplicates(inplace=True)

坑2:去重后索引不连续

# 问题:去重后索引跳号df=df.drop_duplicates()print(df.index)# 0, 1, 3, 5, 7... 跳号# 解决:重置索引df=df.drop_duplicates().reset_index(drop=True)

坑3:keep=False和keep='first’混淆

# keep='first'(默认):保留第一条,删除后续重复df.drop_duplicates(subset=['ID'])# 保留第一条# keep='last':保留最后一条df.drop_duplicates(subset=['ID'],keep='last')![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3bdd971d4db44e109f464076dbc87db1.png#pic_center)# keep=False:删除所有重复行(包括第一条)# 用于找出所有有重复的记录duplicates=df[df.duplicated(subset=['ID'],keep=False)]# 这个不是drop_duplicates,是duplicated

坑4:大小写不同的"重复"

# 问题:"Apple"和"apple"被认为是不同的df.drop_duplicates(subset=['产品名'])# 不会去掉大小写不同的重复# 解决:先标准化再去重df['产品名_std']=df['产品名'].str.lower().str.strip()df=df.drop_duplicates(subset=['产品名_std'])df=df.drop(columns=['产品名_std'])

坑5:多列去重时某列有空值

# 问题:空值和空值不算重复# 两行都是(张三, NaN),drop_duplicates认为不重复df.drop_duplicates(subset=['姓名','邮箱'])# 两行(张三, NaN)都保留了![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/53a5c1d422cf4e11808efc1f332424ab.png#pic_center)![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b71c252f345e4286ba4e103d787b9e7c.png#pic_center)# 解决:空值填充统一值df['邮箱']=df['邮箱'].fillna('无邮箱')df=df.drop_duplicates(subset=['姓名','邮箱'])