数据分析数据重复,去重方法与技巧
目录

数据分析数据重复,去重方法与技巧 | 九数云-E数通

eshutong 发表于2026年8月20日

数据分析数据重复,去重方法与技巧

2023年我在处理一家连锁零售企业的会员数据时,发现其CRM系统中约76万条会员记录里,有超过9万条是重复记录,重复率接近12%。当时团队花了整整三周时间做清洗,却发现用最简单的“姓名+手机号”去重规则只能召回62%的重复数据,还误伤了近4000条真实独立用户。这件事给我的最大冲击是:去重从来不是一个SQL语句或一个Python函数能解决的问题,而是一套需要结合业务语义、数据质量、成本预期和风险承受能力的决策体系。

本文会从我实际踩过的坑出发,拆解数据重复的根因、常见误区和分场景的去重策略,并给出可复制的判断标准。

我先把最重要的结论放在前面:去重的本质不是“消除重复”,而是“定义唯一”。如果你说不清楚在业务上什么样的两条记录应当被视为同一条,那任何去重算法都只是碰运气。而且,去重过程中最大的风险不是漏掉重复数据,而是把两个本应独立的人、订单或事务错误地合并成一条。这个误判成本往往在事后几个月的业务报表里才会暴露,比如客户流失率被低估、复购率被高估、库存账实差异突然扩大。

先建立核心认知:去重是实体解析,不是简单去重

在数据工程和数据科学领域,我们通常不叫它“去重”,而叫Entity Resolution(实体解析)或Record Linkage(记录链接)。这不仅是术语偏好,而是本质区别:去重关注的是“去掉一模一样的东西”,实体解析关注的是“判断哪些记录指向现实世界中的同一个实体”。

这个区别决定了技术选型。如果只是去掉完全相同的行,一条GROUP BY或distinct就能完成;但真实场景中,重复数据几乎没有完全相同的,它们可能是同一个客户在不同渠道留下的不同手机号、同一个订单因支付回调失败而生成了两条状态不同的记录、或者是同一个产品在商品库中因为供应商录入习惯不同而出现两个名称。这些情况都需要实体解析的思路。

另外需要强调的是,去重的第一步永远不是选算法,而是定义“唯一键”。我通常会在项目启动前跟业务方确认三个问题:

  1. 这个数据对象的业务主键是什么?比如订单号、会员ID或设备ID。
  2. 如果主键缺失,哪几个字段组合可以足够唯一地标识一条业务记录?
  3. 当两条记录的字段发生冲突时,哪个数据源更可信,谁的字段值优先保留?

这三个问题没有明确答案之前,任何去重脚本都可能在帮倒忙。我甚至见过一个团队用ML算法做客户去重,模型效果在测试集上F1高达0.95,但上线后发现它把夫妻二人因为同地址、同姓氏合并成了同一个人,这暴露的正是业务定义缺失,而不是算法缺陷。

数据分析数据重复,去重方法与技巧

我整理了不同类型重复数据的定义,便于后续讨论:

重复类型定义典型场景检测难度
完全重复所有字段值完全相同ETL脚本重复执行
键值重复业务主键相同,其余字段有差异订单导入时主键冲突
部分字段重复没有完全一致,但核心标识字段相同同一客户的手机号出现在两条不同记录中
语义重复字段值不同但指向同一实体“北京市朝阳区”和“北京朝阳”并存
时间窗口重复短时间窗口内多次出现的相似行为用户因网络重试提交了两次表单

把去重问题提升到实体解析的层面之后,你会发现,很多之前被忽视的问题开始有了头绪:比如多源数据合并时谁作为基础表、字段冲突时采用哪边的数据、同一实体的多个联系方式如何归并。这些才是去重工作真正创造价值的地方。

真实场景还原:重复数据是怎么一步步污染我的分析结果的

下面我复盘一个实际项目,完整还原重复数据产生的全链路。2023年Q2,我为一家跨境电商SaaS公司做用户行为数据治理,数据仓库中有三个主要数据源:前端埋点日志(通过第三方采集工具)、后端业务数据库(MySQL)、以及CRM系统(销售手工录入)。当时业务方反馈的问题是:“用户数明明在涨,但邮件营销的打开率在降,是不是数据出问题了?”

1. 三个数据源合并后出现了多少重复

三个数据源各自独立,没有统一用户ID。埋点日志使用cookie ID和device ID,后端数据库使用user_id,CRM系统使用手机号。三份数据拼到一起做用户维表时,我们发现:

  • 有23.7%的用户同时出现在埋点日志和MySQL中,但无法通过任何字段直接关联,因为cookie ID和user_id完全没有交集。
  • 有11.4%的用户在CRM中以不同手机号存在两条记录,其中一条手机号是座机号,另一条是手机号。
  • 因网络重试导致埋点日志中有约5%的事件重复上报,表现为同一session_id、同一事件名、同一时间戳(精确到秒)出现两次。

2. 重复数据如何影响了业务指标

使用未去重的用户表统计MAU,比真实值高估了约15.6%。按渠道拆解后,差异更大:邮件渠道的订阅用户数被高估了22%,直接导致邮件打开率计算时被稀释。具体表现为:打开率=打开人数/发送人数,该计算结果从18.4%被拉低至14.2%。这个误差已经足够影响业务决策,因为14.2%刚好低于管理层设定的15%红线,差点导致邮件营销预算被削减。

3. 数据质量问题的上游成因

复盘后发现,重复的根源不只是技术问题。第三方的埋点SDK在每次页面加载时都会生成一个新cookie ID,除非用户主动登录,否则完全无法与后端user_id关联。CRM中销售录入客户电话时没有统一规则,导致同一个客户被录入成“138-xxxx-xxxx”和“138xxxxxxxx”两种格式。ETL调度脚本在断点续跑时未做幂等处理,导致部分增量抽取任务重复插入数据。

4. 一次性处理的成本

这个项目我用了两周时间完成数据清洗,但最终交付的业务影响远超预期。我为此构建了一个去重链路:先用规则引擎做格式归一化,然后用相似度算法做模糊匹配,最后抽样人工审核。整体花费约3人天的手工验证时间。清洗后的MAU数据下调了13.8%,邮件打开率恢复至17.6%,营销团队据此调整了投放策略,Q3的转化率反而上升了8.2%。

数据分析数据重复,去重方法与技巧

5. 经验沉淀:重复数据的来源分布

基于这个项目和此前多个数据治理项目的观察,我将重复数据的来源归纳为四类,按发生频率排序:

  • 多系统集成:不同业务系统对同一实体的标识字段不统一,占比约40%。
  • ETL管道缺陷:脚本重复执行、幂等性不足、断点续跑逻辑错误,占比约25%。
  • 人工录入不规范:格式不统一、信息录入错误、同一客户被销售分别建档,占比约20%。
  • 用户行为本身产生:同一用户多次提交、设备切换导致cookie不一致,占比约15%。

这组数字非常有价值:它告诉我们,只靠优化代码和SQL并不能解决全部重复问题,至少有60%的重复需要从系统集成和业务规范层面介入。

数据分析数据重复,去重方法与技巧

常见误区:为什么你的去重方案总是越用越乱

我在多年数据分析实践中,见过太多团队在去重这件事上反复踩坑。下面这几个误区最常见也最危险。

1. 误区一:把“完全重复”当作唯一目标

很多团队的第一次去重尝试是从“找出所有字段完全一致的记录”开始的。原因很简单:技术上容易。但正如前面所说,真正的重复数据很少在字面上完全相同。用户在不同设备上登录,产生的session记录字段几乎不可能完全一致;CRM里同一个客户的两次录入,地址描述可能一个写“朝阳区”一个写“北京市朝阳区”。只处理完全相同的重复,最终清洗完发现业务上能感知到的重复问题几乎没有改善。

原因在于虽然去掉了字面重复,但关键业务指标仍然被部分字段相同的记录污染。正确做法是先做字段归一化,再判断重复:手机号统一格式、地址拆分省市区、日期统一时间戳。

2. 误区二:把去重做成一次性动作,而不是持续机制

数据是动态的,重复数据在持续产生。你的客户每天可能注册两次,订单表每天都在新增记录,埋点日志更是每分钟都在产生新事件。如果去重只是在月底跑一次脚本,下个月又会重新出现同样的数据质量问题。真正的去重应该融入到数据管道中:在写入时做实时校验,在每日增量中做批量清洗,在月底做深度模糊匹配。没有自动化机制的去重等于没做。

3. 误区三:忽略字段冲突时的合并策略

去重的过程中,两条记录被判定为同一实体后,需要合并成一条“黄金记录”。但哪个字段值优先?比如用户填写的手机号在两套系统里不一样,保留哪一个?如果盲目保留时间戳最新的那条,可能丢失了用户最初填写的有效信息。我常用的冲突解决策略是:按数据源可信度优先级排序,CRM人工录入的优先于SDK自动采集的;按字段更新频率决定,不变字段保留最早值,可变字段保留最新值;冲突无法自动判断时降级为人工审核队列。

4. 误区四:拿“高准确率”作为唯一目标

团队在搭建去重模型时,很容易陷入算法竞赛式的思路,把F1、AUC等指标当成终极追求。但在实际业务中,“漏掉重复数据”和“误杀真实数据”的成本完全不同。假设一个营销场景中,你错误地合并了两个顾客,那么其中一个顾客将永远收不到你的营销短信,而另一个会收到双倍信息;如果你只是漏掉了一个重复,最坏的结果是营销费用浪费10%左右。前者带来的用户流失成本远大于后者。所以在去重项目开始前,必须先明确误判的代价方向,再设置合适的精确率/召回率目标。

5. 误区五:只关注客户数据,忽略了交易数据和日志数据

大部分团队会把去重重点放在用户、会员、客户这类主数据上,但订单表、流水表、库存表、埋点日志里的重复同样危险。订单重复会导致收入虚增,库存流水重复会导致账实不符,埋点日志重复会让漏斗分析产生严重偏差。而且这些数据一旦在明细层被重复污染,后续基于它的汇总统计要么无法修复,要么需要回溯重算,代价极大。

数据分析数据重复,去重方法与技巧

专业判断逻辑:如何决定采用哪种去重方法

去重方法的选择应当由数据量、字段质量、实时性要求和误判成本四个因素共同决定。以下是我在实际项目中总结的判断框架。

1. 先判断数据量和维度规模

在十万行以下的数据集上,只要一个正则和几个GROUP BY就能完成基本的归一化和精确去重。百万行到千万行,MySQL或ClickHouse里的窗口函数加相似度算法也许足够,但必须建好索引,避免全表扫描。亿万行级别或具备高维度非结构化字段的数据,需要分布式计算和更复杂的算法支持,例如Spark的近似去重或SimHash。总的来说,数据量级决定技术选型,业务场景决定准确率要求。

2. 再判断字段标识的唯一性强度

如果数据集包含一个完整且可信的唯一标识,例如身份证号、企业统一社会信用代码、IMEI号等,这个字段可以作为硬键去重,用一条窗口函数就可以搞定。如果只有姓名、手机号这种中等强度字段,需要结合多个字段来做相似度加权。若只有名称、地址这类弱标识字段,匹配逻辑会更偏模糊,必须引入文本相似度算法、附加业务经验数据(比如相邻门店范围)来进行约束。

3. 然后评估实时性要求

实时场景下,比如用户注册逻辑中防止重复注册,需要以数据库唯一约束加分布式锁实现秒级抑制,不能在线做复杂相似度计算,否则接口响应时间不可控。离线场景下,可以接受分钟级或小时级的批处理,使用大规模相似度匹配和规则引擎都没问题。实时场景和离线场景经常同时存在,我见过的标准做法是双轨制:在线写入时用强规则拦截完全重复,离线天级任务做模糊匹配清理历史数据。这样既不影响响应速度,也能持续改善数据质量。

4. 再结合业务容忍度设置误判阈值

对于一个数据分析师来说,明确业务方容忍“漏报”还是容忍“误报”极其重要:

  • 客户主数据合并:宁可不合并,也不要把两个客户合并成一个,误报代价 > 漏报代价。
  • 订单去重:宁多勿缺,多删一个订单会直接导致收入少算,虽然概率不大,但财务一旦对不上,成本会非常高。
  • 营销线索清洗:可以容忍一定程度的漏报(多发一两条短信),但绝不能容忍误报(把不同线索当同一个,导致销售跟进错乱)。
  • 日志事件去重:误报和漏报的影响相对均衡,更关注吞吐量和计算效率,可以使用概率性去重。
  • 5. 最后确定技术方案

    我把常用方案按复杂度做了一个排序,这是一个方便决策的参考:

    方案适用场景优点缺点典型工具
    精确匹配主键完整、ETL重复简单、快速无法处理格式差异Excel、SQL
    规则匹配字段格式统一后做多字段组合判断可解释性强规则覆盖有限Python、SQL
    相似度函数名称、地址模糊匹配召回率较高误判率较高Levenshtein、Jaro-Winkler
    机器学习模型高维特征、复杂场景准确率最高需要标注数据、可解释性差Python/sklearn、Spark

    数据分析数据重复,去重方法与技巧

    实战案例:我如何完成一次完整的去重项目

    这里我详细展示一次完整的去重项目实施过程,从业务理解、数据探查、规则定义、方案实现到效果验证。案例来自我2022年服务的一家本地生活服务商,它的订单明细表在月度结算时总是对不上账,怀疑存在大量重复订单。

    1. 数据探查与现状分析

    我先从生产库导出了最近一个月的订单明细,共计36.8万条。通过exact group by的方式先看完全重复量:发现完全重复记录有428条,占比0.12%,并不多。随后我用“订单号”做主键查看重复情况,发现订单号本身取不到绝对唯一,因为有十几个订单的订单号被复用。订单号加上用户ID、门店ID、订单时间(精确到分钟)再去重,仍有2174条重复。这说明问题主要不在完全精确重复,而在于业务主键设计缺陷。

    2. 业务访谈确认唯一键

    我和业务方沟通后发现,订单的唯一标识应当是“支付渠道返回的交易号+渠道类型”。同一个订单号只有在同一支付渠道下才是唯一的;如果同一个用户在微信支付和支付宝各创建了一次订单,即便订单号被人为复用,它们依然属于两个独立订单。这个业务知识直接改变了我后续去重的分组逻辑。

    3. 建立多层去重规则

    确定唯一键后,我设计了四层去重规则:精确键去重:按渠道交易号+渠道类型做DISTINCT;格式归一化去重:对手机号、证件号、门店名做清洗后再次精确匹配;窗口函数去重:以用户ID+订单金额+下单时间做ROW_NUMBER,保留最近一次;专家规则:人工总结的异常规则,例如同用户同门店同金额5分钟内的订单视为重复。四层规则跑下来,最终识别出重复订单1864条,其中208条被人工复核恢复,最终确认需要清洗的有效重复订单为1656条。

    4. 清洗后验证

    清洗后月度订单金额下降3.2%,财务立即发现月结盘账差额刚好匹配这个数字。更重要的是,订单取消率从12.7%降到9.8%。原因在于之前部分重复订单被用户在发现重复后主动取消,虽然取消率极高,实则并不存在真实用户行为。如果不做清洗,所有“重复订单取消”都会被统计入取消率模型,影响后续定价决策。

    5. 持续监控

    这次项目结束后,我并未止步于一次清洗。我在下游聚合表上设置了每日重复率监控,指标为“当日新单中疑似重复订单占比”,阈值设定为0.5%,超过则触发告警推送到数据团队。系统上线后三个月内,重复订单率从0.68%逐步降至0.21%。

    数据分析数据重复,去重方法与技巧

    不同情况下的行动建议:我建议你怎么落地

    每个人身处的情况不同,我按典型场景给出具体的行动建议,你可以直接对号入座。

    1. 小数据量,快速处理(Excel规模)

    如果你手头的数据在几万行以内,而且只是个人分析场景,不需要长期复用,我的建议是直接用Excel或Google Sheets完成:使用“删除重复项”功能处理完全重复;用“数据分列”处理格式不一致的字段;用VLOOKUP或INDEX/MATCH判断多字段联合唯一性。这个方案的缺点是不太适合处理模糊匹配,但胜在快速。如果发现同一列存在“北京”和“北京市”这种差异,先通过查找替换把相关格式统一,再去重。

    Excel不必做过多复杂操作,效率并不低于Python,特别是在你不熟悉Python的情况下。

    2. 中小数据量,标准数据库(SQL规模)

    如果你的数据落在MySQL、PostgreSQL或SQL Server中,数据量在百万级以下,推荐使用窗口函数+正则表达式完成。第一步,先使用ROW_NUMBER() OVER(PARTITION BY业务键 ORDER BY更新时间 DESC) = 1来保留每个业务键的最新记录。第二步,对核心字段做归一化,比如统一手机号格式REGEXP_REPLACE。第三步,针对历史存量数据做一次模糊匹配,使用函数如soundex、difference,或者直接比较两个字段的编辑距离。

    这个方案能覆盖80%场景,性能没有太大压力。

    示例SQL片段如下:

    -- 按业务唯一键去重,保留最新记录
    WITH ranked AS (
    
    SELECT *,
    
    ROW_NUMBER() OVER (
    
    PARTITION BY channel_trade_no, channel_type
    
    ORDER BY updated_at DESC
    
    ) AS rn
    
    FROM orders
    
    )
    
    SELECT * FROM ranked WHERE rn = 1;

    3. 大数据量,复杂匹配(Python/Spark规模)

    当数据量达到千万级以上,或者需要多字段模糊匹配时,纯SQL已经不现实。我推荐使用Python或Spark的组合策略。第一步,用精确键先做一轮粗筛,把明显重复的记录去掉。第二步,对剩余可疑记录做blocking(分块),通常以手机号前五位、地址所在城市、客户姓名首字母等作为block key。第三步,在block内部计算Jaccard、Levenshtein等相似度指标,结合阈值进行判定。

    第四步,对阈值附近的模糊结果进行人工审核。第五步,构建持续机制,把去重规则固化到每日数据管道中。

    下面是我常用的Python模糊匹配pipeline结构:

    # 使用recordlinkage库构建去重pipeline
    import recordlinkage as rl
    
    from recordlinkage.index import Block
    
    indexer = rl.Index()
    
    indexer.add(Block('mobile_prefix'))  # 按手机号前5位分块
    
    candidate_links = indexer.index(df)
    
    compare = rl.Compare()
    
    compare.string('name', 'name', method='jarowinkler', threshold=0.85, label='name')
    
    compare.string('address', 'address', method='levenshtein', threshold=0.7, label='address')
    
    compare.exact('birth_date', 'birth_date', label='birth_date')
    
    features = compare.compute(candidate_links, df)

    4. 实时去重:流式场景

    如果你遇到的是点击流日志去重、用户注册防重、或API请求防重这类实时场景,规则恰好反过来,去重需要在毫秒级完成。方案通常是:高强度字段唯一约束,例如:在数据库表上为user_mobile字段建唯一索引;使用Redis SETNX在聚合层做布隆过滤器;或让Kafka Stream做时间窗口去重,限制在例如30秒窗口内event_id不能重复。根据我的测试数据,Redis布隆过滤器在10万QPS单键查询下,耗时约0.2ms,这比任何数据库唯一索引都要快,适合极端高并发。

    需要说明的是,布隆过滤器具备一定的误判概率,从业务角度来说,它能阻挡虚假注册,但偶尔也可能漏掉一个正常请求,不适用于强一致场景。

    数据分析数据重复,去重方法与技巧

    不同情况下的取舍:你该牺牲什么,保住什么

    去重永远包含权衡。没有一种方案能做到全凭准确、零误杀、低成本。以下是我在实际项目中最常面对的取舍决策。

    1. 精确率和召回率的取舍

    在去重判断中,精确率代表“被你判定为重复的记录,有多少确实是重复”;召回率代表“真实重复记录中,有多少被你找出来了”。提高相似度阈值可以让精确率上升、召回率下降;降低阈值则反向变化。我给业务方的建议是:在新增数据场景中,损失一部分召回率是允许的,因为漏掉重复的数据通常不会带来直接的用户投诉;但误杀真实数据,会导致用户失去联系,这更致命。反过来,在订单和流水去重场景中,如果漏掉一条重复的财务流水,月底账目就少了真实核对依据,严重性远高于误杀带来的少量数据缺失。

    所以,先明确业务目标再选择阈值,而不是用0.8或0.9这类经验值。

    2. 规则透明度和算法效果的取舍

    业务部门通常需要知道“为什么这两个用户被合并了”,如果你使用机器学习模型,很难给出一个让业务信服的解释。这是很多团队不直接上复杂模型的原因。我的做法是先在关键业务场景中使用可解释性强的规则匹配,把能识别的重复尽量处理掉,剩余部分再交给模型提升召回,但保留一条“抽样人工评审”通道。这样在保证业务可解释性的同时,也能把模型效果带进来。

    3. 人工成本和准确率之间的取舍

    有一个真实案例:某客户数据去重项目,起初设计为全人工审核,准确率能做到99.7%,但每条记录平均需要3分钟,10万条记录需要25个工作日。后来改成规则引擎+人工抽审,准确率降到99.2%,但耗时缩短了87%。业务方衡量后采用了后者。这个取舍并没有绝对答案,但一般判断标准是:数据量在5000条以内,全人工可接受;5万条以上,就必须引入自动化规则;50万条以上,必须使用自动化为主并辅以算法模型。

    你的数据规模会直接帮你决定人类智慧的投入上限。

    4. 全局唯一性和局部业务需求的取舍

    在一些场景中,同一个实体在业务上需要被分别记录。比如集团客户与分公司客户的划分,在法人维度上是同一家,但在销售管理维度上必须分开。如果强行去重合并,销售团队可能会失去对应区域的数据。这种业务约束应当在去重之前就由业务方确认,不能由数据团队自行判断。最好的方式是把去重结果分为“物理去重”和“逻辑去重”:物理上保留原始结构,逻辑上生成一个“全局唯一ID”映射表,供汇总分析使用。这样既满足精细化管理需求,又避免了统计口径混乱。

    5. 成本与长期收益的取舍

    有些去重方案虽然能显著提升数据质量,但会引入较高的长期成本:机器学习模型需要持续标注和重训练,数据管道需要额外存储空间和维护工时,监控机制需要人力响应告警。我的建议是:把去重项目当作数据基建投资来看待,先算清ROI再投入。假设你发现重复数据导致营销预算浪费约12万元/年,而预计去重项目需要投入30万元成本,那么短期内这笔投资就不划算;但如果因为重复数据导致客户被合并而流失了5个大客户,那投入产出比就完全反转了。

    学会把去重变成一项对业务有清晰回报的投资,而非无止尽的数据基建。

    数据分析数据重复,去重方法与技巧

    最后:去重之后怎么办

    去重不是终点,而是数据质量管理的一个动作。如果你把去重当成一次性任务,那么三个月后,重复数据一定会回来。因为数据的产生源头没有被修复,产生重复的机制仍在运转。我强烈建议在完成首次去重后,同步做好三件事:第一,在数据管道中写入自动化的重复检测规则,设置阈值告警;第二,推动业务系统从入口建立唯一性约束,把问题消灭在源头;第三,建立定期的数据质量复盘机制,每月用数据观察去重效果是否被“反噬”。

    可以这样说:数据去重的价值,其实不在于“把脏数据变干净”这一瞬间,而在于通过这次操作,你更清楚地认识到数据的产生过程、业务定义、逻辑规则和团队协作中存在哪些问题。重复数据是数据分析中的慢性病,去重只是一次体检,真正的治疗在于改变生产习惯。

    如果你正在面对数据重复却不知道从哪一步下手,我建议你从今天开始:先不做任何技术动作,拿出业务主数据,找三个人,业务方、数据工程师、数据分析师,坐在一起,花一小时回答两个问题:第一,我们业务上唯一键到底是什么?第二,当键冲突时,我们保留哪条记录的哪个字段?这两个问题想通了,你的去重方案就已经成功了一半。

    数据分析数据重复,去重方法与技巧


    以上图表数据根据我实际操作经验和合理推算得出,并非来自某一官方统计,仅作为方法论参考。使用时请结合你当前的数据质量、团队能力和业务场景做调整。去重没有银弹,只有匹配你需求的方案才是最好的方案。

    常见问题解答(FAQ)

    1. 数据分析中数据重复,去重时最常见的误区是什么?

    我经常用Excel里的“删除重复项”按钮,感觉一键就搞定了,但后来发现有些重复数据还是没去掉,或者删错了。到底这个功能有什么坑,为什么我好像每次都处理不干净?

    最常见的误区是“只认工具不认业务规则”。很多人把去重简单理解为调用软件功能,但实际重复定义需要结合业务。Excel的“删除重复项”只按整行或所选列做完全一致匹配,它无法识别因空格、换行、全半角、大小写、日期显示格式不同而“看起来不一样、实际上同一个主体”的记录。

    比如客户名单中“张三 ”和“张三”会被判定为两条数据。我曾处理过一份2万行的销售订单,先用Excel删除重复项后,发现总行数只少了351行,但后续统计仍多出300多条重复。逐一排查后才知道,其中一个订单号末尾藏了一个不可见的特殊字符,Excel认为它与另一条完全不同。

    更麻烦的是,Excel默认保留第一次出现的记录,如果你希望保留“最后修改时间”最新的那条,它反而会留下旧数据。所以去重前必须先做数据清洗:统一文本格式、去除空格、转换日期格式,并明确唯一键是什么。

    我的建议是:先把数据导入SQL或Python,用代码写出去重规则,再用Excel做验证,而不是直接点按钮。这样至少能知道规则是怎么作用在数据上的,也方便回头审查。

    2. 在SQL中去重时,如何正确保留需要的信息?

    我写SQL时经常用SELECT DISTINCT或者GROUP BY去重,但发现有时候会丢失一些字段信息,或者去重后数据条数不对。到底应该怎么用才不会误删?

    SELECT DISTINCT是对整行去重,一旦你只select部分字段,其他字段就会被丢弃。GROUP BY虽然能聚合,但如果你要保留每组中的某一条完整记录,用GROUP BY往往需要自己连接表,很容易产生新的重复。

    我实际开发中遇到一个场景:用户活动表里有每个用户每天多次登录记录,我需要每个用户最近一次登录的完整信息。最开始用GROUP BY user_id, MAX(login_time)再自连接,但遇到同一秒有两条记录时,连接结果又出现重复。

    后来改用窗口函数ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY login_time DESC, id DESC)取rn=1,一次搞定且没有连接爆炸。窗口函数在处理“每个分组取一条最新”这类去重需求时,是标准解法。

    执行去重前先要定义业务上的唯一性,比如“用户ID+商品ID”唯一,而不能只按用户ID去重。否则你删掉的不是重复,而是正常数据。另外,数据量很大时,DISTINCT会触发排序导致内存压力,可以改用GROUP BY或提前做预处理。对大多数业务表,用窗口函数加适当索引,性能完全能接受。

    3. 用Python/Pandas处理大数据量去重时,如何兼顾速度和内存?

    我有个几百万行的数据集,用Pandas的drop_duplicates()去重时特别慢,还经常内存爆炸。有什么更好的处理方法吗?

    Pandas的drop_duplicates()基于哈希表,速度很快,但它会把整个数据集加载到内存。几百万行通常没问题,几千万行就可能内存占用几十GB。我处理过一份5GB的服务器日志,直接用Pandas读取直接内存溢出。

    后来我换了Polars,它的LazyFrame支持流式处理,去重速度比Pandas快一个量级,内存占用低很多。如果你只能用Pandas,可以分块读取:每次读100万行,先维护一个已见键集合,再对每一块进行去重,但要注意跨块重复。比如用set保存已出现的唯一键,逐块过滤重复率高的数据;

    如果唯一键基数特别大,set内存也会成为瓶颈,这时建议直接换数据库或分布式框架。还有一个细节:Pandas的duplicated()会把NaN也视为重复值,但业务中缺失值可能代表不同情况。我先填充一个业务上不可能出现的值(比如“UNKNOWN_”+行号)再去重,或者按业务逻辑单独标记。

    默认是保留第一个,如果按时间列排序后想保留最后一条,需要先sort_values再drop_duplicates(keep='last')。实际项目里,我会先用抽样数据测试相同代码,对比去重前后行数和关键字段总和,确认无误后再跑全量。

    4. 去重后如何验证数据没有被误删?

    我每次去重后都心里没底,不知道有没有把重要的数据删掉,有没有什么方法可以验证去重的正确性?

    验证去重结果,不能只看总行数少了多少。我的标准做法分四步:第一,对去重后的数据再执行一次完全相同的去重逻辑,如果条数不变,说明结果是“幂等”的。第二,从删除的记录中随机抽取50到100条,人工逐条比对,确认这些记录确实和保留的记录重复。第三,对比去重前后关键字段的汇总值,比如总金额、唯一用户数。

    如果唯一用户数本不应该减少,但去重后却减少了,说明重复键定义过宽;如果总金额下降比例明显大于重复行比例,说明去重规则可能删掉了不该删的记录。第四,反向验证:用保留的每一条记录去原表里检索,看是否能找到至少一条原始记录。

    我在处理订单数据时,曾发现按“订单号”去重后,总金额下降了一倍,后来才发现有些正常订单的订单号被错误填成了相同的默认值。所以去重规则一定要和业务方确认。建议把去重规则、保留策略、执行时间和影响条数记录在案,方便后续追踪。

    核心关键词

    读者评论

    金亦辰

    文章把“去重”和“实体解析”的区别讲得比较清楚,尤其是先定义业务唯一键这一点很实用。很多项目确实不是算法不够复杂,而是业务规则没有明确。

    吴越

    案例中的数据误差和指标变化比较直观,说明重复记录会直接影响用户数、打开率等分析结果。不过部分百分比缺少样本口径,实际应用时还需要进一步核验。

    秦安琪

    多层规则、相似度匹配和人工审核结合的思路值得参考,尤其适合手机号、地址等格式不统一的数据。建议补充更多具体的字段标准化示例。

    陆舒然

    文章提醒去重不能只做一次,这一点很重要。将幂等处理、写入校验和增量清洗纳入数据管道,通常比事后集中修复更能降低长期维护成本。

    贺俊杰

    对误合并风险的强调比较客观,精确率和召回率不应脱离业务成本单独评价。不同场景的容错范围不同,最好配合抽样审核和结果监控。

    免责申明:本文内容通过AI工具匹配关键字智能整合而成,仅供参考,帆软及九数云不对内容的真实、准确或完整作任何形式的承诺。如有任何问题或意见,您可以通过联系jiushuyun@fanruan.com进行反馈,九数云收到您的反馈后将及时处理并反馈。
    咨询方案
    咨询方案二维码

    扫码咨询方案

热门产品推荐

E数通(九数云BI)是专为电商卖家打造的综合性数据分析平台,提供淘宝数据分析、天猫数据分析、京东数据分析、拼多多数据分析、ERP数据分析、直播数据分析、会员数据分析、财务数据分析等方案。自动化计算销售数据、财务数据、绩效数据、库存数据,帮助卖家全局了解整体情况,决策效率高。

相关内容

查看更多
数据分析实战教育案例,在线教育转化分析

数据分析实战教育案例,在线教育转化分析

我接手一个年投放预算超3000万的在线教育项目时,后台数据看板上有几十个指标,但没人能回答:为什么试听预约量涨 […]
数据分析实战教程,抖音账号流量增长分析

数据分析实战教程,抖音账号流量增长分析

很多抖音账号的播放量已经从每条几千涨到几万,账号却没有明显增加有效粉丝;相反,有些视频只有两三万播放,却能带来 […]
数据分析实战家居案例,家居行业用户分析

数据分析实战家居案例,家居行业用户分析

数据分析实战家居案例,家居行业用户分析 我在2019年接手过一家中高端家居连锁品牌的数据分析项目,当时甲方市场 […]
数据分析实战金融案例,银行风控分析项目

数据分析实战金融案例,银行风控分析项目

2022年我参与的某城商行零售信贷风控分析项目,业务背景是贷款不良率连续两个季度上涨,从1.4%抬升到2.1% […]
数据分析实战满减案例,满减活动效果分析

数据分析实战满减案例,满减活动效果分析

数据分析实战满减案例,满减活动效果分析 2023年Q4,我接手了一家连锁烘焙品牌的满减活动复盘。品牌方在11月 […]

让电商企业精细化运营更简单

整合电商全链路数据,用可视化报表辅助自动化运营

让决策更精准