Дубли: duplicated и drop_duplicates по ключевым столбцам
Содержание курса
Параметр keep: управление тем, что считается дублем
Когда duplicated() находит группу строк с одинаковыми значениями по subset, она должна решить: какую из них считать «оригиналом», а какие — дублями. Этим управляет параметр keep.
По умолчанию keep='first': первое вхождение получает False (не дубль), все последующие — True. При keep='last' логика зеркальная: последнее вхождение считается «оригиналом», все предыдущие помечаются True.
import pandas as pd
df = pd.DataFrame({
'user_id': [1, 2, 1, 3, 2],
'action': ['login', 'buy', 'login', 'view', 'buy'],
'amount': [0, 100, 0, 50, 200]
})
key_cols = ['user_id', 'action']
print(df.duplicated(subset=key_cols, keep='first').tolist())
# [False, False, True, False, True]
print(df.duplicated(subset=key_cols, keep='last').tolist())
# [True, True, False, False, False]
Здесь строки 0 и 2 — это пара (1, 'login'). При keep='first' дублем считается строка 2; при keep='last' — строка 0. Строки 1 и 4 — пара (2, 'buy'): аналогично меняется, кто из них получает True.
Третье значение — keep=False — отличается принципиально: дублями помечаются все строки группы, включая первое вхождение.
print(df.duplicated(subset=key_cols, keep=False).tolist())
# [True, True, True, False, True]
Это удобно для диагностики: чтобы увидеть все строки, участвующие в дублировании, достаточно отфильтровать по этой маске:
print(df[df.duplicated(subset=key_cols, keep=False)])
# user_id action amount
# 0 1 login 0
# 1 2 buy 100
# 2 1 login 0
# 4 2 buy 200
Один из важных практических нюансов: если передать keep=False не в duplicated(), а в drop_duplicates(), результат будет удалять все строки с дублями — включая «оригиналы». То есть из таблицы исчезнут все четыре строки выше, а не только «лишние» копии. Для большинства задач это не то, что нужно.
Правило простое: keep=False — инструмент диагностики, чтобы посмотреть на проблему. Для реального удаления используй keep='first' или keep='last', явно выбирая, какую запись из группы сохранить.
