现在位置: 首页 > Pandas 教程 > 正文

Pandas df.drop_duplicates() 函数

Pandas 常用函数 Pandas 常用函数


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)

运行结果预期:

原始数据:
    姓名  年龄  部门
0  张三   25  技术
1  李四   30  市场
2  张三   25  技术
3  王五   35  技术
4  李四   30  市场
==================================================
删除重复行后的数据:
    0  姓名  年龄  部门
0  张三   25  技术
1  李四   30  市场
3  王五   35  技术

代码解析:

  1. 原始数据中,第0行和第2行完全相同(张三,25岁,技术部门)。
  2. 第1行和第4行也完全相同(李四,30岁,市场部门)。
  3. 使用 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)

运行结果预期:

原始数据:
    姓名  年龄  部门
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)

运行结果预期:

原始数据:
    学号  姓名  成绩
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)

    运行结果预期:

    原始数据:
       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)

    运行结果预期:

    原始数据:
        姓名  城市
    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)

    运行结果预期:

    原始订单数据:
        订单号  客户名  金额   日期
    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
    

    代码解析:

    1. 原始数据有6行,存在2个重复订单(O001和O002各出现两次)。
    2. 使用 drop_duplicates(subset=['订单号']) 根据订单号去重。
    3. 结合列选择 [['订单号', '客户名', '金额']],只保留需要的列。

    注意事项

    • drop_duplicates() 默认不会修改原始 DataFrame,如果想原地修改,使用 inplace=True 参数。
    • 使用 subset 参数时,只根据指定的列来判断重复,其他列的值不会影响判断。
    • 使用 keep=False 会删除所有重复行,可能导致数据大量丢失,请谨慎使用。
    • 在删除重复数据前,建议先分析重复的原因,确保删除操作符合业务逻辑。
    • 如果数据中有缺失值(NaN),默认会将它们视为相同的值来进行比较。

    Pandas 常用函数 Pandas 常用函数