drop_duplicates()默认整行去重,需用subset指定列;unique()返回无索引的唯一值数组,性能更快;duplicated()返回布尔标记,适合条件筛选;类型优化(如category)可提升去重效率。

用 drop_duplicates() 直接删重行,但要注意默认行为
默认情况下,drop_duplicates() 是对整行去重,不是单列。如果只想基于某一列(比如 'user_id')判断重复,必须显式指定 subset 参数,否则可能误删本该保留的行。
常见错误现象:执行 df.drop_duplicates() 后发现数据量没变,或结果不符合预期——大概率是忘了 subset。
- 只保留第一次出现的
'email'值对应整行:df.drop_duplicates(subset=['email']) - 保留最后一次出现的:
df.drop_duplicates(subset=['email'], keep='last') - 直接删掉所有重复项(不保留任何一次):
df.drop_duplicates(subset=['email'], keep=False)
只要去重后的列值?用 unique() 或 dropna().unique()
unique() 返回的是 numpy.ndarray,不是 DataFrame,适合只需要值列表的场景,比如构造下拉选项、做集合运算。
性能上比 drop_duplicates() 快不少,因为它不维护原始索引、不返回 DataFrame 结构,纯提取唯一值。
- 基础用法:
df['city'].unique() - 排除空值再取唯一值(避免
NaN混在结果里):df['city'].dropna().unique() - 转成 Python 列表便于后续处理:
df['city'].dropna().unique().tolist()
想保留原索引并生成新列?别用 drop_duplicates(),改用 duplicated()
当你要标记哪些行是重复的(比如加一列 is_first_occurrence),duplicated() 更灵活。它返回布尔 Series,可直接用于过滤或赋值。
注意:duplicated() 默认标记“后续重复项”为 True,即第一次出现是 False,第二次及以后是 True。这点和 keep='first' 的逻辑一致,但方向相反。
- 标记每组
'order_id'中非首次出现的行:df['is_duplicate'] = df.duplicated(subset=['order_id']) - 反向标记首次出现(即去重后要保留的行):
df['keep_flag'] = ~df.duplicated(subset=['order_id']) - 配合布尔索引直接筛选:
df[~df.duplicated(subset=['order_id'])]等价于drop_duplicates(subset=['order_id'], keep='first'),但更透明
大数据量时 drop_duplicates() 变慢?检查数据类型和内存布局
字符串列去重慢,往往不是算法问题,而是 object 类型导致哈希开销大、缓存不友好。如果该列实际是分类有限的标签(如国家名、状态码),转成 category 类型能显著提速,内存也更省。
另一个容易被忽略的点:未排序的数据调用 drop_duplicates() 无法利用局部性,而某些底层优化(如 PyArrow backend)在有序列上表现更好——不过 Pandas 默认不依赖顺序。
- 提速操作:
df['status'] = df['status'].astype('category'),再执行去重 - 确认当前类型:
df['col'].dtype,避免误以为是string实际却是object - 极端情况可考虑
pd.array(..., dtype="string")(Pandas 1.0+ 的新 string 类型),比object更高效
unique() 和 drop_duplicates() 当成等价操作混用——前者丢索引、不保证顺序(虽然通常保持首次出现顺序,但文档不承诺),后者保留原始索引和行结构。选哪个,取决于你下一步要接什么逻辑。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











