Найти строки с одинаковыми значениями в pd.df [duplicate]

Представьте, что у вас есть продукт под названием «Zebra», который может быть дополнен плагинами. Он находит плагины, ища библиотеки DLL в некоторых каталогах. Он загружает все эти DLL и использует отражение для поиска любых классов, которые реализуют IZebraPlugin, а затем вызывает методы этого интерфейса для связи с плагинами.

Это делает его полностью независимым от какого-либо конкретного класса плагина - ему все равно, что представляют собой классы. Он заботится только о том, чтобы они соответствовали спецификации интерфейса.

Интерфейсы - это способ определения точек расширяемости, подобных этому. Код, который говорит с интерфейсом, более слабо связан - на самом деле он не связан вообще с каким-либо другим конкретным кодом. Он может взаимодействовать с плагинами, написанными годами позже людьми, которые никогда не встречались с оригинальным разработчиком.

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

26
задан Elsalex 19 August 2015 в 11:10
поделиться

4 ответа

Вы можете сделать это, используя группу:

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)

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

EDIT: от 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
34
ответ дан JoeCondron 18 August 2018 в 17:30
поделиться

Вы можете сделать это с помощью 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()
0
ответ дан AlexT 18 August 2018 в 17:30
поделиться

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

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

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

df.groupby(['A', 'B']).max()['C'].reset_index()
7
ответ дан b10n 18 August 2018 в 17:30
поделиться
  • 1
    Это просто вернет Серию максимального значения C в каждой группе, проиндексированную «A» и «B». – JoeCondron 19 August 2015 в 11:36
  • 2
    отредактирован, чтобы включить возможность возврата кадра данных – b10n 19 August 2015 в 11:40
  • 3
    Вы прочитали вопрос? Проблема состоит в том, чтобы удалить строки, содержащие только строки с максимальным значением «C» для каждой группы A-B. Вы не предложили ничего, чтобы решить эту часть проблемы – JoeCondron 19 August 2015 в 11:42
  • 4
    df.groupby(['A', 'B']).max()['C'].reset_index() возвращает ожидаемый выход OPs. – b10n 19 August 2015 в 11:47
  • 5
    Извините, вы правы. Извиняюсь. – JoeCondron 19 August 2015 в 12:29

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

df.drop_duplicates(['A','B'],keep= 'last')
2
ответ дан Sudharsan 18 August 2018 в 17:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: