Представьте, что у вас есть продукт под названием «Zebra», который может быть дополнен плагинами. Он находит плагины, ища библиотеки DLL в некоторых каталогах. Он загружает все эти DLL и использует отражение для поиска любых классов, которые реализуют IZebraPlugin
, а затем вызывает методы этого интерфейса для связи с плагинами.
Это делает его полностью независимым от какого-либо конкретного класса плагина - ему все равно, что представляют собой классы. Он заботится только о том, чтобы они соответствовали спецификации интерфейса.
Интерфейсы - это способ определения точек расширяемости, подобных этому. Код, который говорит с интерфейсом, более слабо связан - на самом деле он не связан вообще с каким-либо другим конкретным кодом. Он может взаимодействовать с плагинами, написанными годами позже людьми, которые никогда не встречались с оригинальным разработчиком.
Вместо этого вы можете использовать базовый класс с виртуальными функциями - все плагины будут получены из базового класса. Но это гораздо более ограничивает, потому что класс может иметь только один базовый класс, тогда как он может реализовать любое количество интерфейсов.
Вы можете сделать это, используя группу:
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
Вы можете сделать это с помощью 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()
Я думаю, что groupby должен работать.
df.groupby(['A', 'B']).max()['C']
Если вам нужна обратная передача данных, вы можете связать вызов индекса сброса.
df.groupby(['A', 'B']).max()['C'].reset_index()
df.groupby(['A', 'B']).max()['C'].reset_index()
возвращает ожидаемый выход OPs.
– b10n
19 August 2015 в 11:47
Вы можете сделать это, просто используя функцию дублирования pandas drop
df.drop_duplicates(['A','B'],keep= 'last')