Pandas df.drop_duplicates() 函数
df.drop_duplicates() 是 Pandas 中用于删除重复行的函数。
在数据采集和整合过程中,重复数据是常见的问题。drop_duplicates() 可以帮助你根据指定的列或全部列来识别和删除重复的行,保留第一个或最后一个出现的记录。这对于数据去重、确保数据唯一性非常有用。
基本语法与参数
drop_duplicates() 是 DataFrame 的成员函数,通过点运算符 . 来调用。
语法格式
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)
参数说明
| 参数 | 类型 | 是否必填 | 说明 | 默认值 |
|---|---|---|---|---|
| subset | column label 或 list | 可选 | 指定用于判断重复的列。如果为 None,则使用所有列。可以是单个列名或列名列表。 |
None |
| keep | str 或 False | 可选 | 指定保留哪一条重复记录。'first' 保留第一条;'last' 保留最后一条;False 删除所有重复记录。 |
'first' |
| inplace | bool | 可选 | 如果为 True,直接在原 DataFrame 上修改,不返回新对象;如果为 False,返回一个新的 DataFrame,原数据不变。 |
False |
| ignore_index | bool | 可选 | 如果为 True,重置结果的索引,从0开始编号;如果为 False,保留原始索引。 |
False |
返回值说明
- 返回一个新的 DataFrame(如果
inplace=False),或者None(如果inplace=True)。 - 返回的 DataFrame 中不包含重复的行。
实例
让我们通过一系列例子,彻底掌握 drop_duplicates() 的用法。
示例 1:删除完全重复的行
默认情况下,会根据所有列来判断是否为重复行。
实例
import pandas as pd
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'年龄': [25, 30, 25, 35, 30],
'部门': ['技术', '市场', '技术', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除重复行,保留第一次出现的记录
df_cleaned = df.drop_duplicates()
print("删除重复行后的数据:")
print(df_cleaned)
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'年龄': [25, 30, 25, 35, 30],
'部门': ['技术', '市场', '技术', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除重复行,保留第一次出现的记录
df_cleaned = df.drop_duplicates()
print("删除重复行后的数据:")
print(df_cleaned)
运行结果预期:
原始数据:
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
2 张三 25 技术
3 王五 35 技术
4 李四 30 市场
==================================================
删除重复行后的数据:
0 姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
3 王五 35 技术
代码解析:
- 原始数据中,第0行和第2行完全相同(张三,25岁,技术部门)。
- 第1行和第4行也完全相同(李四,30岁,市场部门)。
- 使用
drop_duplicates()默认参数,删除了重复的行,保留了第一次出现的位置。
示例 2:根据指定列删除重复行
可以使用 subset 参数只根据特定列来判断重复。
实例
import pandas as pd
import numpy as np
# 创建一个 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'年龄': [25, 30, 28, 35], # 张三出现了两次,但年龄不同
'部门': ['技术', '市场', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 只根据"姓名"列判断重复
df_cleaned = df.drop_duplicates(subset=['姓名'])
print("根据姓名列删除重复后的数据:")
print(df_cleaned)
print("=" * 50)
# 根据"姓名"和"部门"两列判断重复
df_cleaned2 = df.drop_duplicates(subset=['姓名', '部门'])
print("根据姓名和部门列删除重复后的数据:")
print(df_cleaned2)
import numpy as np
# 创建一个 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'年龄': [25, 30, 28, 35], # 张三出现了两次,但年龄不同
'部门': ['技术', '市场', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 只根据"姓名"列判断重复
df_cleaned = df.drop_duplicates(subset=['姓名'])
print("根据姓名列删除重复后的数据:")
print(df_cleaned)
print("=" * 50)
# 根据"姓名"和"部门"两列判断重复
df_cleaned2 = df.drop_duplicates(subset=['姓名', '部门'])
print("根据姓名和部门列删除重复后的数据:")
print(df_cleaned2)
运行结果预期:
原始数据:
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
2 张三 28 技术 # 虽然姓名重复,但年龄不同
3 王五 35 市场
==================================================
根据姓名列删除重复后的数据:
姓名 年龄 部门
0 张三 25 技术 # 保留第一条张三的记录
2 张三 28 技术
3 王五 35 市场
==================================================
根据姓名和部门列删除重复后的数据:
参数
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
3 王五 35 市场
代码解析:
- 根据姓名列判断时,第0行和第2行的姓名都是"张三",被认为是重复行,只保留第0行。
- 根据姓名和部门两列判断时,第0行和第2行的姓名和部门都相同,保留第0行。
示例 3:保留最后一条重复记录
使用 keep='last' 参数可以保留最后出现的重复记录。
实例
import pandas as pd
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'学号': ['S001', 'S002', 'S001', 'S003', 'S002'],
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'成绩': [85, 90, 88, 92, 85] # 同一个学号,成绩可能不同
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 保留第一条记录(默认)
df_first = df.drop_duplicates(subset=['学号'], keep='first')
print("保留第一条重复记录:")
print(df_first)
print("=" * 50)
# 保留最后一条记录
df_last = df.drop_duplicates(subset=['学号'], keep='last')
print("保留最后一条重复记录:")
print(df_last)
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'学号': ['S001', 'S002', 'S001', 'S003', 'S002'],
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'成绩': [85, 90, 88, 92, 85] # 同一个学号,成绩可能不同
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 保留第一条记录(默认)
df_first = df.drop_duplicates(subset=['学号'], keep='first')
print("保留第一条重复记录:")
print(df_first)
print("=" * 50)
# 保留最后一条记录
df_last = df.drop_duplicates(subset=['学号'], keep='last')
print("保留最后一条重复记录:")
print(df_last)
运行结果预期:
原始数据:
学号 姓名 成绩
0 S001 张三 85
1 S002 李四 90
2 S001 张三 88 # 同一个人,成绩不同
3 S王五 92
4 S002 李四 85 # 同一个人,成绩不同
==================================================
保留第一条重复记录:
学号 姓名 成绩
0 S001 张三 85 # 保留第一个85分
1 S002 李四 90 # 保留第一个90分
3 王五 92
==================================================
保留最后一条重复记录:
学号 姓名 成绩
2 S001 张三 88 # 保留最后一个88分
3 王五 92
4 S002 李四 85 # 保留最后一个85分
代码解析:
- 学号 S001 有两条记录,成绩分别是85和88,使用
keep='first'保留85分那条,keep='last'保留88分那条。 - 学号 S002 同样有两记录,成绩分别是90和85。
- 根据业务需求选择保留第一条还是最后一条。
示例 4:删除所有重复记录
使用 keep=False 可以删除所有重复记录,只保留完全不重复的行。
实例
import pandas as pd
import numpy as np
# 创建一个 DataFrame
data = {
'A': [1, 1, 2, 2, 3],
'B': [1, 1, 2, 2, 3],
'C': [1, 2, 3, 3, 5]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除所有重复行(不保留任何重复)
df_cleaned = df.drop_duplicates(keep=False)
print("删除所有重复行后的数据:")
print(df_cleaned)
import numpy as np
# 创建一个 DataFrame
data = {
'A': [1, 1, 2, 2, 3],
'B': [1, 1, 2, 2, 3],
'C': [1, 2, 3, 3, 5]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除所有重复行(不保留任何重复)
df_cleaned = df.drop_duplicates(keep=False)
print("删除所有重复行后的数据:")
print(df_cleaned)
运行结果预期:
原始数据: A B C 0 1 1 1 1 1 1 2 # 与第0行A和B相同,是重复行 2 2 2 3 3 2 2 3 # 与第2行完全相同,是重复行 4 3 3 5 ================================================== 删除所有重复行后的数据: A B C 4 3 3 5
代码解析:
- 第0行和第1行的A和B列值相同,是重复行,由于
keep=False,两条都被删除。 - 第2行和第3行同样完全重复,都被删除。
- 只有第4行是完全唯一的,被保留下来。
示例 5:重置索引
删除重复行后,原始索引可能会不连续,可以使用 ignore_index=True 重置索引。
实例
import pandas as pd
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'城市': ['北京', '上海', '北京', '广州']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除重复行,不重置索引
df_cleaned1 = df.drop_duplicates()
print("删除重复行(保留原始索引):")
print(df_cleaned1)
print("=" * 50)
# 删除重复行,重置索引
df_cleaned2 = df.drop_duplicates(ignore_index=True)
print("删除重复行(重置索引):")
print(df_cleaned2)
import numpy as np
# 创建一个包含重复行的 DataFrame
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'城市': ['北京', '上海', '北京', '广州']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 删除重复行,不重置索引
df_cleaned1 = df.drop_duplicates()
print("删除重复行(保留原始索引):")
print(df_cleaned1)
print("=" * 50)
# 删除重复行,重置索引
df_cleaned2 = df.drop_duplicates(ignore_index=True)
print("删除重复行(重置索引):")
print(df_cleaned2)
运行结果预期:
原始数据:
姓名 城市
0 张三 北京
1 李四 上海
2 张三 北京
3 王五 广州
==================================================
删除重复行(保留原始索引):
姓名 城市
0 张三 北京
1 李四 上海
3 王五 广州
==================================================
删除重复行(重置索引):
姓名 城市
0 张三 北京
1 李四 上海
2 王五 广州
代码解析:
- 不使用
ignore_index时,删除第2行后,索引为0、1、3,不连续。 - 使用
ignore_index=True后,索引重新从0开始编号,为0、1、2。
示例 6:结合其他操作
drop_duplicates() 可以与其他 DataFrame 操作结合使用。
实例
import pandas as pd
import numpy as np
# 模拟一个从数据库查询得到的数据
data = {
'订单号': ['O001', 'O002', 'O001', 'O003', 'O002', 'O004'],
'客户名': ['张三', '李四', '张三', '王五', '李四', '赵六'],
'金额': [100, 200, 100, 300, 200, 400],
'日期': ['2024-01-01', '2024-01-02', '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04']
}
df = pd.DataFrame(data)
print("原始订单数据:")
print(df)
print("=" * 50)
# 查看有多少重复订单
print(f"总行数: {len(df)}")
print(f"去重后行数: {len(df.drop_duplicates())}")
print(f"重复行数: {len(df) - len(df.drop_duplicates())}")
print("=" * 50)
# 实际去重,保留第一条记录,并只保留需要的列
df_unique = df.drop_duplicates(subset=['订单号'])[['订单号', '客户名', '金额']]
print("去重后的订单数据:")
print(df_unique)
import numpy as np
# 模拟一个从数据库查询得到的数据
data = {
'订单号': ['O001', 'O002', 'O001', 'O003', 'O002', 'O004'],
'客户名': ['张三', '李四', '张三', '王五', '李四', '赵六'],
'金额': [100, 200, 100, 300, 200, 400],
'日期': ['2024-01-01', '2024-01-02', '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04']
}
df = pd.DataFrame(data)
print("原始订单数据:")
print(df)
print("=" * 50)
# 查看有多少重复订单
print(f"总行数: {len(df)}")
print(f"去重后行数: {len(df.drop_duplicates())}")
print(f"重复行数: {len(df) - len(df.drop_duplicates())}")
print("=" * 50)
# 实际去重,保留第一条记录,并只保留需要的列
df_unique = df.drop_duplicates(subset=['订单号'])[['订单号', '客户名', '金额']]
print("去重后的订单数据:")
print(df_unique)
运行结果预期:
原始订单数据:
订单号 客户名 金额 日期
0 O001 张三 100 2024-01-01
1 O002 李四 200 2024-01-02
2 O001 张三 100 2024-01-01 # 重复订单
3 O003 王五 300 2024-01-03
4 O002 李四 200 2024-01-02 # 重复订单
5 O004 赵六 400 2024-01-04
================================================++
总行数: 6
去重后行数: 4
重复行数: 2
代码解析:
- 原始数据有6行,存在2个重复订单(O001和O002各出现两次)。
- 使用
drop_duplicates(subset=['订单号'])根据订单号去重。 - 结合列选择
[['订单号', '客户名', '金额']],只保留需要的列。
注意事项
drop_duplicates()默认不会修改原始 DataFrame,如果想原地修改,使用inplace=True参数。- 使用
subset参数时,只根据指定的列来判断重复,其他列的值不会影响判断。 - 使用
keep=False会删除所有重复行,可能导致数据大量丢失,请谨慎使用。 - 在删除重复数据前,建议先分析重复的原因,确保删除操作符合业务逻辑。
- 如果数据中有缺失值(NaN),默认会将它们视为相同的值来进行比较。

Pandas 常用函数