Обработка дубликатов данных в Pandas

Дублирующиеся данные — распространённая проблема в анализе данных, которая может влиять на точность статистических результатов. Pandas предоставляет всесторонний функционал для обнаружения и обработки дублирующихся данных.


Обнаружение дублирующихся данных

метод duplicated

Пример

import pandas as pd

# Создать DataFrame, содержащий дублирующиеся строки
df = pd.DataFrame({
    "Имя": ["Чжан Сань", "Ли Сы", "Ван У", "Чжан Сан", "Ли Сы", "Чжао Лю"],
    "Возраст": [25, 30, 28, 25, 30, 35],
    "Город": ["Пекин", "Шанхай", "Гуанчжоу", "Пекин", "Шэньчжэнь", "Пекин"]
})

print("Исходные данные:")
print(df)
print()

# Обнаружить дублирующиеся строки (по умолчанию помечает с первого вхождения, keep='first')
print("Обнаружены дублирующиеся строки:")
print(df.duplicated())
print()

# Подсчитать количество дублирующихся строк
print(f"Количество дублирующихся строк: {df.duplicated().sum()}")
print()

# Обнаружить дубликаты в конкретном столбце
print("Обнаружение дубликатов по столбцу 'Name':")
print(df.duplicated(subset=["Name"]))

параметр keep

Пример

import pandas as pd

df = pd.DataFrame({
    "Name": ["Zhang San", "Li Si", "Zhang San", "Wang Wu", "Li Si"],
    "Возраст": [25, 30, 25, 28, 30]
})

print("Исходные данные:")
print(df)
print()

# keep='first': сохранить первое вхождение (по умолчанию)
print("keep='first' (по умолчанию):")
print(df.duplicated(keep="first"))
print()

# keep='last': сохранить последнее вхождение
print("keep='last':")
print(df.duplicated(keep="last"))
print()

# keep=False: отметить все дубликаты (не сохранять ни одного)
print("keep=False (отметить все дубликаты):")
print(df.duplicated(keep=False))

Удаление дублирующихся данных

Базовое использование drop_duplicates

Пример

import pandas as pd

df = pd.DataFrame({
    "Name": ["Zhang San", "Li Si", "Zhang San", "Wang Wu", "Li Si"],
    "Возраст": [25, 30, 25, 28, 30],
    "Город": ["Пекин", "Шанхай", "Пекин", "Гуанчжоу", "Шэньчжэнь"]
})

print("Исходные данные:")
print(df)
print()

# Удалить дублирующиеся строки (по умолчанию сохраняется первая)
print("Удалить дублирующиеся строки (сохранить первую):")
print(df.drop_duplicates())
print()

# Оставить последнюю
print("Удалить дублирующиеся строки (оставить последнюю):")
print(df.drop_duplicates(keep="last"))
print()

# Не оставлять ни одной дублирующейся строки
print("Удалить все дублирующиеся строки:")
print(df.drop_duplicates(keep=False))

Удаление дубликатов по столбцу

Пример

import pandas as pd

df = pd.DataFrame({
    "Name": ["Zhang San", "Li Si", "Zhang San", "Ван У"],
    "Возраст": [25, 30, 35, 28],
    "Город": ["Пекин", "Шанхай", "Пекин", "Гуанчжоу"]
})

print("Исходные данные:")
print(df)
print()

# Удалить дубликаты по одному столбцу
print("Удалить дубликаты по столбцу 'Name':")
print(df.drop_duplicates(subset=["Name"]))
print()

# Удалить дубликаты по комбинации нескольких столбцов
print("Удалить дубликаты по комбинации 'Name'+'City':")
print(df.drop_duplicates(subset=["Name", "City"]))
print()

# Оставить строку с максимальным значением в конкретном столбце
print("Сгруппировать по 'Name', оставить строку с наибольшим возрастом:")
print(df.sort_values("Age", ascending=False).drop_duplicates(subset=["Name"], keep="first"))

Практика: очистка данных

Комплексный пример

Пример

import pandas as pd
import numpy as np

# Создать смоделированные данные заказов (содержащие дубликаты)
orders = pd.DataFrame({
    "Order ID": ["O001", "O002", "O001", "O003", "O002", "O004"],
    "Customer ID": ["C001", "C002", "C001", "C003", "C002", "C004"],
    "Product": ["iPhone", "MacBook", "iPhone", "iPad", "AirPods", "Apple Watch"],
    "Количество": [8000, 12000, 8000, 5000, 1500, 3000],
    "Date": ["2024-01-01", "2024-01-02", "2024-01-01", "2024-01-03", "2024-01-02", "2024-01-04"]
})

print("Исходные данные заказа:")
print(orders)
print()

# 1. Обнаружение дубликатов заказов
print("Обнаружение дубликатов заказов:")
duplicates = orders[orders.duplicated(subset=["Order ID"], keep=False)]
print(duplicates)
print()

# 2. Удаление полностью дублирующихся заказов
orders_clean = orders.drop_duplicates()
print("После удаления полных дубликатов:")
print(f"Исходно {len(orders)} строк -> {len(orders_clean)} строк")
print()

# 3. Удаление дубликатов по Order ID с сохранением самых новых
# Предполагаем, что последняя запись — самая новая
orders_clean = orders.sort_values("Date").drop_duplicates(
    subset=["Order ID"],
    keep="last"
).sort_index()

print("Удаление дубликатов по Order ID (оставить самые новые):")
print(orders_clean)

Продвинутое использование

Сохранение определённых строк по группам

Пример

import pandas as pd

df = pd.DataFrame({
    "Customer": ["A", "A", "A", "B", "B", "B"],
    "Month": ["01", "02", "03", "01", "02", "03"],
    "Spending": [100, 200, 150, 300, 250, 280]
})

print("Исходные данные:")
print(df)
print()

# Оставить месяц с наибольшими расходами для каждого клиента
print("Месяц с наибольшими расходами для каждого клиента:")
result = df.sort_values("Spending", ascending=False).drop_duplicates(
    subset=["Customer"],
    keep="first"
).sort_values("Customer")
print(result)
print()

# Оставить первую запись для каждого клиента (по месяцу)
print("Первая запись для каждого клиента:")
result = df.sort_values("Month").drop_duplicates(
    subset=["Customer"],
    keep="first"
)
print(result)

Пометка дубликатов вместо удаления

Пример

import pandas as pd

df = pd.DataFrame({
    "Name": ["Zhang San", "Li Si", "Zhang San", "Wang Wu", "Li Si"],
    "Город": ["Пекин", "Шанхай", "Пекин", "Гуанчжоу", "Шэньчжэнь"]
})

# Добавить столбец-флаг дубликата
df["Is Duplicate"] = df.duplicated(subset=["Name"], keep=False)

print("Отметить строки-дубликаты:")
print(df)
print()

# Или пометить с помощью groupby
df["Duplicate Count"] = df.groupby("Name")["Name"].transform("count")
df["Is First"] = ~df.duplicated(subset=["Name"], keep="first")

print("Количество дубликатов по группам:")
print(df)

Примечания

1. Различайте "полные дубликаты" и "частичные дубликаты"

Полные дубликаты означают, что все значения столбцов одинаковы, тогда как частичные дубликаты означают, что совпадают определённые столбцы. Используйтеsubsetпараметр для указания столбцов для обнаружения дубликатов.

2. Выбор стратегии сохранения

Выберите, сохранять первый, последний или ни один, исходя из бизнес-требований. Выбор того, что сохранить, может повлиять на последующие результаты анализа.

3. Влияние типа данных

Типы данных учитываются при обнаружении дубликатов. Например, целое число 1 и число с плавающей запятой 1.0 считаются разными.

Перед удалением дублирующихся данных рекомендуется сначала проанализировать причину и распределение дубликатов, чтобы убедиться, что операция удаления не потеряет важную информацию.

Другие расширения