drop_duplicates()高效去重需匹配参数、数据类型与意图:忘设subset将整行比对;多列去重传列表;nan默认相等;唯一值列表优先用unique();字符串列转category可提速30%–70%;duplicated()更适合标记筛选。

drop_duplicates() 是 Pandas 中处理大规模去重的主力方法,但“高效”不等于“无脑调用”。实际跑 10 万+ 行时,性能差异可能达数倍——关键在参数选择、数据类型和操作意图是否匹配。
drop_duplicates() 忘写 subset 就等于白干
默认行为是整行比对,不是按某列去重。你本想基于 user_id 去重,却执行了 df.drop_duplicates(),结果发现重复没少——因为两行其他字段(比如时间戳、日志ID)不同,整行就不算重复。
- 只看
email列是否重复:用df.drop_duplicates(subset=['email']) - 多列联合判断(如
user_id+action_type):传列表subset=['user_id', 'action_type'] - 如果
subset里有空值(NaN),Pandas 默认把所有NaN视为相等,这点常被忽略
要的是唯一值列表?别用 drop_duplicates(),改用 unique()
如果你最终只需要一列的去重结果(比如导出所有不重复的省份名、生成下拉选项),drop_duplicates() 是杀鸡用牛刀:它返回完整 DataFrame,保留索引、列结构、内存开销大。
- 直接取值:
df['province'].unique()→ 返回numpy.ndarray,快且轻量 - 排除空值干扰:
df['province'].dropna().unique() - 转成 Python 列表供后续使用:
df['province'].dropna().unique().tolist() - 注意:
unique()不保证顺序稳定(尤其含NaN时),若需严格按首次出现顺序,仍得用drop_duplicates(subset=['province'])['province'].tolist()
大数据量卡顿?先查 category 类型和内存布局
字符串列(object dtype)是去重慢的头号元凶。哈希计算开销大、缓存不友好、GC 压力高。如果你的 status 列只有 “pending”, “done”, “failed” 三种值,却存为 object,那必须改。
- 转成
category:df['status'] = df['status'].astype('category') - 效果:内存可降 5–10 倍,
drop_duplicates()耗时通常下降 30%–70% - 额外好处:
category列在groupby、merge等操作中也更快 - 验证是否生效:
df['status'].dtype应返回category,而非object
duplicated() 比 drop_duplicates() 更适合标记和条件筛选
当你需要的不是“删掉重复”,而是“标出哪些该留、哪些该剔除、哪些要告警”,duplicated() 的布尔输出更灵活透明。
- 标记所有非首次出现的行:
df['is_dup'] = df.duplicated(subset=['order_id']) - 反向得到保留标记:
df['keep'] = ~df.duplicated(subset=['order_id']) - 配合布尔索引过滤,语义清晰:
df[~df.duplicated(subset=['order_id'])]等价于df.drop_duplicates(subset=['order_id'], keep='first'),但逻辑可读性更强 - 注意:
duplicated()默认keep='first',即第一次出现为False,后续为True;这点和drop_duplicates(keep='first')的保留逻辑一致,但方向相反
unique()、drop_duplicates()、duplicated() 各自解决的问题边界完全不同;而一个 astype('category') 调用,可能比优化循环快十倍。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











