Подтвердить что ты не робот

Python (pandas): удаление дубликатов на основе двух столбцов, содержащих строку с максимальным значением в другом столбце

У меня есть dataframe, который содержит дубликаты значений в соответствии с двумя столбцами (A и B):

A B C
1 2 1
1 2 4
2 7 1
3 4 0
3 4 8

Я хочу удалить дубликаты, сохраняя строку с максимальным значением в столбце C. Это приведет к:

A B C
1 2 4
2 7 1
3 4 8

Я не могу понять, как это сделать. Должен ли я использовать drop_duplicates(), что-то еще?

4b9b3361

Ответ 1

Вы можете сделать это с помощью группы:

c_maxes = df.groupby(['A', 'B']).C.transform(max)
df = df.loc[df.C == c_maxes]

c_maxes - это Series максимальных значений C в каждой группе, но одинаковой длины и с тем же индексом, что и df. Если вы не использовали .transform тогда печать c_maxes может быть хорошей идеей, чтобы посмотреть, как она работает.

Другой подход с использованием drop_duplicates будет

df.sort('C').drop_duplicates(subset=['A', 'B'], take_last=True)

Не уверен, что является более эффективным, но я думаю, что первый подход, поскольку он не включает сортировку.

РЕДАКТИРОВАТЬ: От pandas 0.18 выше, второе решение будет

df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last')

или, альтернативно,

df.sort_values('C', ascending=False).drop_duplicates(subset=['A', 'B'])

В любом случае groupby решение кажется значительно более эффективным:

%timeit -n 10 df.loc[df.groupby(['A', 'B']).C.max == df.C]
10 loops, best of 3: 25.7 ms per loop

%timeit -n 10 df.sort_values('C').drop_duplicates(subset=['A', 'B'], keep='last')
10 loops, best of 3: 101 ms per loop

Ответ 2

Я думаю, что groupby должен работать.

df.groupby(['A', 'B']).max()['C']

Если вам нужен обратный кадр данных, вы можете связать индексный вызов reset.

df.groupby(['A', 'B']).max()['C'].reset_index()

Ответ 3

Вы можете сделать это, просто используя функцию pandas drop duplicates

df.drop_duplicates(['A','B'],keep= 'last')

Ответ 4

Вы можете сделать это с помощью drop_duplicates, как вы хотели

# initialisation
d = pd.DataFrame({'A' : [1,1,2,3,3], 'B' : [2,2,7,4,4],  'C' : [1,4,1,0,8]})

d = d.sort_values("C", ascending=False)
d = d.drop_duplicates(["A","B"])

Если важно получить тот же порядок

d = d.sort_index()