Подготовка датафрейма
Рассмотрим поиск и удаление дубликатов в следующем наборе данных:
brand style rating 0 Yum Yum cup 4.0 1 Yum Yum cup 4.0 2 Yum Yum cup 4.0 3 Indomie cup 3.5 4 Indomie pack 15.0 5 Indomie pack 5.0
Преобразуем данную структуру данных в датафрейм используюя библиотеку pandas.
import pandas as pd df = pd.DataFrame({ 'brand': ['Yum Yum', 'Yum Yum', 'Yum Yum', 'Indomie', 'Indomie', 'Indomie'], 'style': ['cup', 'cup', 'cup', 'cup', 'pack', 'pack'], 'rating': [4, 4, 4, 3.5, 15, 5] })
Поиск дубликатов в датафрейме
В pandas есть встроенная функция duplicated()
для поиска дубликатов в датафрейме.
Вариант «по-умолчанию» предполагает, что поиск дубликатов будет осуществлен построчно, где для каждой строки будут проверяться совпадения во всех ее колонках. На выходе вы получите срез датафрейма, где для каждого индекса будет проставлен в формате bool признак о найденном совпадении:
> df.duplicated() # out 0 False 1 True 2 True 3 False 4 False 5 False dtype: bool
Как видите, каждая следующая запись, определенная как дубликат, помечается флагом True. Но бывают задачи, в которых требуется считать последнюю найденную запись как «оригинал», а все совпадения которые были до нее считать как «дубликат».
Передача доп. параметра keep=’last’ дает возможность не считать дубликатом только последнюю найденную запись:
> df.duplicated(keep='last') # out 0 True 1 True 2 False 3 False 4 False 5 False dtype: bool
А передача доп. параметра keep=False дает возможность отметить дубликатами все записи имеющие совпадения.
> df.duplicated(keep=False) #out 0 True 1 True 2 True 3 False 4 False 5 False dtype: bool
Также есть возможность делать проверку на дубликаты при совпадении значений не во всех колонках, а только в определенных, указав их явно при помощи параметра subset. Причем, данный параметр можно указывать совместно с keep.
> df.duplicated(subset=['brand','style']) #out 0 False 1 True 2 True 3 False 4 False 5 True dtype: bool
Как отфильтровать данные без учета дубликатов
Для этого нужно применить стандартный механизм фильтрации данных в датафрейме на основе его признаков. В данном случае признак у нас один — это флаг наличия дубликата в соответствии с индексом наших данных, т.е. то выражение которое мы разбирали выше. Его мы и передадим в датайрейм, поставив перед ним знак ~, что означает отфильтровать все записи, которые не являются True (т.е не являются дубликатами). Если же не указать ~, то отфильтруется наоборот — т.е. останутся только дубликаты.
# короткий формат записи df[~df.duplicated(subset=['brand','style'])] # тоже самое, но более подробно через промежуточную переменную dpl, где ~ заменяется на явное указание False dpl = df.duplicated(subset=['brand','style']) df[dpl == False]
Как удалить дубликаты
Дубликаты удаляются точно так же, как осуществляется их поиск, который мы разобрали выше, но вместо функции поиска дубликатов df.duplicated()
используется функция их удаления df.drop_duplicates()
. Также обратите внимание, при удалении вы точно также как и при поиске можете указывать все те же параметры: keep и subset для уточнения критериев определения дубликатов.
> df.drop_() #out brand style rating 0 Yum Yum cup 4.0 3 Indomie cup 3.5 4 Indomie pack 15.0 5 Indomie pack 5.0