重复行会导致统计偏差和冗余计算。pandas 提供 duplicated() 与 drop_duplicates() 两兄弟完成重复值的检测与删除。


1. 检测重复行:duplicated()

duplicated() 返回布尔 Series,标记哪些行是重复的(默认除第一次出现外,后续均标记为 True)。

参数详解

参数说明
subset仅检查指定列(默认所有列)
keep保留策略:'first'(默认,保留第一次出现的行)、'last'(保留最后一次)、False(所有重复行均标记)

示例

import pandas as pd
 
df = pd.DataFrame({
    '姓名': ['张三', '李四', '张三', '王五', '张三'],
    '年龄': [25, 30, 25, 40, 25]
})
 
df.duplicated()
# 0    False
# 1    False
# 2     True
# 3    False
# 4     True
# dtype: bool
 
# 标记所有重复行(包括第一次)
df.duplicated(keep=False)
# 0     True
# 1    False
# 2     True
# 3    False
# 4     True
 
# 仅按姓名列判断
df.duplicated(subset='姓名')
# 0    False
# 1    False
# 2     True
# 3    False
# 4     True
 
# 保留最后一次出现
df.duplicated(keep='last')
# 0     True
# 1    False
# 2    False
# 3    False
# 4     True

筛选重复行

# 查看所有重复行(含第一次)
df[df.duplicated(keep=False)]
 
# 查看各列组合的重复次数
df.value_counts()
# 姓名  年龄
# 张三  25    2
# 王五  40    1
# 李四  30    1

2. 删除重复行:drop_duplicates()

drop_duplicates() 删除重复行,返回新 DataFrame(默认)。

参数详解

参数说明
subset仅按指定列去重(默认所有列)
keep'first'(默认,保留第一次)、'last'(保留最后一次)、False(全部删除)
inplace是否原地修改
ignore_index是否重置索引为连续的 RangeIndex

示例

df = pd.DataFrame({
    '姓名': ['张三', '李四', '张三', '王五', '张三'],
    '年龄': [25, 30, 25, 40, 25],
    '城市': ['北京', '上海', '北京', '广州', '深圳']
})
 
# 全列去重
df.drop_duplicates()
#   姓名  年龄 城市
# 0  张三  25  北京
# 1  李四  30  上海
# 3  王五  40  广州
# 4  张三  25  深圳   (注意最后一行姓名年龄相同但城市不同,不算重复)
 
# 按姓名去重,保留第一次出现
df.drop_duplicates(subset='姓名')
#   姓名  年龄 城市
# 0  张三  25  北京
# 1  李四  30  上海
# 3  王五  40  广州
 
# 保留最后一次出现
df.drop_duplicates(subset='姓名', keep='last')
#   姓名  年龄 城市
# 1  李四  30  上海
# 3  王五  40  广州
# 4  张三  25  深圳
 
# 删除所有重复项(keep=False)
df.drop_duplicates(subset=['姓名', '年龄'], keep=False)
#   姓名  年龄 城市
# 1  李四  30  上海
# 3  王五  40  广州
 
# 原地去重并重置索引
df.drop_duplicates(ignore_index=True)

3. 常见场景

场景 1:保留最早记录

df.sort_values('日期').drop_duplicates(subset='用户ID', keep='first')

场景 2:保留最新记录

df.sort_values('日期').drop_duplicates(subset='用户ID', keep='last')

场景 3:部分列去重

# 以“用户 + 商品”组合去重
df.drop_duplicates(subset=['用户ID', '商品ID'])

场景 4:查看重复概览

# 统计重复数量
df.duplicated().sum()
 
# 各组重复情况
df.groupby(['姓名', '年龄']).size().sort_values(ascending=False)

与 value_counts() 配合

使用 df.value_counts() 可快速查看各组合出现的频次,定位哪些行重复最多。

注意

  • drop_duplicates() 默认保留第一次出现的行,若需保留其他行,调整 keep 参数。
  • 去重前建议先 sort_values() 或 sort_index(),确保保留的是符合业务逻辑的记录。
  • inplace=True 不会重置索引,如需连续索引可配合 ignore_index=True。