duplicated() 返回布尔标记识别重复行,默认keep='first'仅标后续重复项,设keep=False可标记全部重复行;value_counts()统计值频次并筛选>1的重复值;groupby().filter()提取重复组全部原始行。

用 duplicated() 找出重复行的布尔标记
duplicated() 是最直接的方式,它返回一个 Series,每个位置为 True 表示该行在它之前已出现过(即“非首次出现”)。默认只检查整行,但配合 subset 参数可限定列:
- 查单列重复:
df.duplicated(subset=['col_name']) - 查多列组合重复:
df.duplicated(subset=['a', 'b']) - 想包含所有重复项(包括第一次出现的)?加
keep=False—— 这是关键,默认keep='first'会把首次出现标为False,容易漏掉“重复组里的第一个” - 注意:结果是布尔型,不是数据本身;要过滤出重复行,得配合布尔索引:
df[df.duplicated(subset=['name'], keep=False)]
用 value_counts() 统计并筛选频次 >1 的值
如果目标是“找出哪些值重复了”,而不是“哪些行重复了”,value_counts() 更直观:
-
df['col'].value_counts()返回从高到低排序的频次统计 - 加
sort=False可保持原始顺序,加dropna=False能把NaN也计入(默认会丢掉) - 筛选重复值:
counts = df['col'].value_counts(); counts[counts > 1] - 性能提示:对超大列,
value_counts(sort=False)比先duplicated()再groupby().size()略快,且内存更友好
用 groupby().filter() 直接提取重复组的全部行
当需要按某列分组,并保留“组内行数 ≥2”的所有原始行时,filter() 最干净:
-
df.groupby('col').filter(lambda x: len(x) > 1)—— 返回所有属于重复组的行,包括每组的第一行 - 比
duplicated(keep=False)多一个优势:能自然支持多列分组,比如df.groupby(['a', 'b']).filter(lambda x: len(x) > 1) - 注意:
filter()对空组或全NaN组行为稳定,但若列含混合类型(如字符串混数字),可能触发TypeError,建议提前确认数据类型
常见陷阱:NaN 和类型不一致导致误判
NaN != NaN,所以默认情况下 duplicated() 和 value_counts() 都把每个 NaN 当作不同值处理 —— 这常被当成 bug,其实是设计如此:
立即学习“Python免费学习笔记(深入)”;
- 想把所有
NaN视为相同并参与去重?先用df.fillna(method='ffill')或填入占位符(如'<na>'</na>),再操作 - 字符串列里混着
int、float或None?value_counts()可能报错或归类混乱;用df['col'].astype(str)强制统一前务必确认业务含义是否允许 - 大小写敏感?
duplicated()默认区分大小写;需忽略时先转小写:df['col'].str.lower().duplicated()
NaN 不参与相等比较,或者忘了 keep=False 才能拿到完整的重复块。


















