duplicated() 默认只标记后续重复行为true,首行为false;用keep=false可标记全部重复行,配合subset可指定列判断重复,需注意nan、字符串格式和时间精度等预处理。

如何用 duplicated() 标记重复行
duplicated() 默认只标记「后续出现的重复行」为 True,首行仍为 False。这意味着它不会把第一次出现的那行当成重复项——这是很多人误以为“没检测出来”的原因。
常见错误现象:df[df.duplicated()] 返回空,但肉眼可见有重复;其实是重复行的第一条被放过了。
- 默认行为等价于
keep='first':保留首次出现的行,标记之后的为重复 -
keep='last':保留最后一次出现的行,标记前面的为重复 -
keep=False:所有重复行(包括首尾)全部标为True,适合要完整提取所有重复记录的场景
提取全部重复行(含首次出现的那条)
想把某组重复数据的所有行都捞出来,不能只靠默认 duplicated(),得配合 keep=False + 布尔索引。
示例:
dup_mask = df.duplicated(keep=False) duplicate_rows = df[dup_mask].copy()
注意:duplicate_rows 里每组重复数据会完整出现多次(比如 3 行相同,则返回这 3 行),不是去重后的“模板行”。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 若只要每组重复数据的代表行(如第一条),用
df.drop_duplicates() - 若要统计每组重复几次,用
df.groupby(list(df.columns)).size() -
duplicated()对NaN的处理是:多行全为NaN会被视为相等,但单个NaN和其它值比较恒为False
按指定列判断重复(忽略某些字段)
实际中往往不看整行,而是关注业务主键列,比如只看 ['user_id', 'order_date'] 是否重复。
直接传列名列表给 subset 参数即可:
df.duplicated(subset=['user_id', 'order_date'], keep='first')
-
subset支持字符串(单列)或字符串列表(多列),不支持正则或位置索引 - 若列中含
datetime64,注意时区和精度是否一致,微秒级差异会导致判为不重复 - 字符串列要提前用
.str.strip()或.str.lower()统一格式,否则空格/大小写不同会被当作不同值
性能与大表注意事项
duplicated() 底层依赖哈希,对百万级以上行数依然较快,但有几点容易被忽略:
- 若 DataFrame 索引混乱(如重复索引、非数值索引),不影响结果,但可能干扰后续定位,建议先
reset_index(drop=True) - 使用
keep=False时内存占用略高,因为需遍历两次:一次建哈希表,一次回标所有匹配项 - 在
groupby().apply()内部调用duplicated()需小心——keep是相对于子组生效,不是全局
真正难的不是调用函数,而是确认“什么是你定义的重复”:字段是否要清洗、空值怎么算、时间精度要不要截断、业务上是否允许部分字段为空却仍视为同一笔记录——这些决定了 subset 和预处理怎么做,而不是 keep 参数本身。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










