July 31, 2022

Удаление строк датафрейма в условиях дублирующихся индексов

При наличии дубликатов в индексах традиционные способы удаления строк могут привести к неожиданных результатам. Рассмотрим датафрейм:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(12).reshape(4,3),index=['one','two','two','three'])
df

Допустим, мы хотим исключить последний повтор (2 строка, начиная от 0). При работе с именами индексов мы не достигнем желаемого результата:

df[~df.index.isin(['two'])]

Встречается и такой вариант:

df.drop(df.iloc[[2]].index)

То есть исключения индекса "two" приводит к удалению обеих строк.

Методы удаления дубликатов из индексов так же не работают, так как при адресации по повторяющемуся индексу извлекаются все повторы (подробнее здесь):

df.index.drop_duplicates()
df.loc[df.index.drop_duplicates()]

Теперь перейдем к тому, как правильно избавляться от дублей в индексе. Например, можно сгруппировать по уникальным значениям индекса (level=0) с выбором первого или последнего значений для дублей:

df.groupby(level=0).first()

Альтернативой является перенос индекса в колонки датафрейма и использование мощи метода drop_duplicates с параметром subset:

df.reset_index().drop_duplicates(subset='index', keep='first').set_index('index')

Другой способ - выбрать порядковые номер дубликатов и избавиться от них:

np.where(df.index.duplicated(keep='first'))

Напомню, что np.where выбирает кортеж индексов (по всем измерениям) ненулевых элементов массива.

l = np.where(df.index.duplicated(keep='first'))[0].tolist()
l
df.iloc[[it for it in range(len(df)) if not it in l]]

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram