duplicated返回False/True混合序列,因默认keep='first'将首次重复行标False、后续同值行标True;可用keep='last'或keep=False调整逻辑,subset参数支持按指定列判重。

为什么 duplicated 返回的不是布尔索引而是 False/True 混合序列
duplicated 本身不修改原数据,只返回一个与 DataFrame 行数等长的 Series,每个元素是 True(该行是重复项且非首次出现)或 False(首次出现,或唯一)。注意:默认情况下它把**第一次出现的重复行标记为 False,后续相同行才标 True**。这容易让人误以为“没标出来”,其实是逻辑设计如此。
常见错误现象:df[df.duplicated()] 看起来“漏掉”了第一组重复值——没错,它就是故意不包含首行。
- 用
keep='first'(默认):首行False,其余同值行True - 用
keep='last':末行False,其余同值行True - 用
keep=False:所有重复行(含首尾)全标True,适合“找出全部重复记录”场景
只看某几列是否重复?传列表给 subset 参数
实际分析中,往往不需要整行完全一致才算重复。比如订单表里可能只关心 'user_id' 和 'order_date' 组合是否重复,其他字段(如金额、状态)允许不同。
直接传列名列表给 subset 即可:
立即学习“Python免费学习笔记(深入)”;
df.duplicated(subset=['user_id', 'order_date'])
注意:subset 中列名必须真实存在,否则抛 KeyError;也支持单列字符串(如 subset='email'),但推荐统一用列表写法,避免类型混淆。
librosa 是一个用于音频和音乐分析的 Python 库。它提供了特征提取、频谱分析、节拍跟踪、起始检测和音频可视化的工具,基于 NumPy 和 SciPy 构建,用于科学音频计算。
- 若列含
NaN,默认会把所有NaN视为相等(即NaN == NaN成立),这是 Pandas 的行为,不是 bug - 想跳过含
NaN的行再判重?先用dropna(subset=[...])预处理,或手动填充
用 duplicated 配合 loc 定位并查看重复行细节
光有布尔序列不够直观,常需要把重复行拎出来看内容。最稳妥方式是用 .loc + 布尔索引,而不是链式布尔切片(易触发 SettingWithCopyWarning)。
示例:查出所有重复订单(含首次出现的那行)
dup_mask = df.duplicated(subset=['user_id', 'order_date'], keep=False)<br>df.loc[dup_mask].sort_values(['user_id', 'order_date'])
这样能清晰看到每组重复记录内部差异。如果只是想剔除重复行,直接用 drop_duplicates() 更高效;但 duplicated 的优势在于——你可以把它当条件参与更复杂的筛选或分组逻辑。
- 别用
df[dup_mask]赋值新列(如df['is_dup'] = dup_mask),除非确认df是视图还是副本,否则可能静默失败 - 若需在原地加标记列,推荐
df.assign(is_dup=dup_mask),安全且函数式
性能和内存要注意:大表慎用 subset 含多列或高基数列
duplicated 底层依赖哈希和排序,当 subset 包含多列、或某列取值极多(如 UUID、时间戳毫秒级)时,哈希碰撞概率上升,性能明显下降,甚至 OOM。
- 测试发现:100 万行 × 3 列
subset(其中一列为object类型 UUID)比单列慢 5–8 倍 - 优化方向:提前对关键列做
astype('category')(若取值有限),或用pd.util.hash_pandas_object()手动构造哈希列再判重 - 极端情况(如日志表按毫秒时间+IP判重),考虑先用
dt.floor('S')降精度,再duplicated
真正难的不是调用函数,而是判断“重复”的业务定义是否合理,以及这个定义在数据规模扩大后还能不能扛住。

















