Удаляйте дубликаты, но сохраняйте строки с наибольшим значением, включая связи - PullRequest
0 голосов
/ 02 января 2019

Я хочу отбросить повторяющиеся значения для col1, сохраняя только строки с самым высоким значением в col2.Пример df:

df1 = pd.DataFrame({'col1': ['a', 'a', 'b', 'b', 'c'],
                   'col2': [5, 5, 10, 15, 20]})

Я знаю, df1.drop_duplicates избавится от повторяющихся значений, но как мне убедиться, что это наибольшее значение, которое сохраняется (или несколько значений, если есть значения, привязанные к наибольшему)??

Желаемый вывод:

dfoutput = pd.DataFrame({'col1': ['a', 'a', 'b', 'c'],
                       'col2': [5, 5, 15, 20]})

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Вы можете использовать rank функцию Pandas:

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

In [126]: df1['rnk'] = df1.groupby('col1')['col2'].rank()
In [127]: df1
Out[127]: 
  col1  col2  rnk
0    a     5  1.5
1    a     5  1.5
2    b    10  1.0
3    b    15  2.0
4    c    20  1.0

Затем используйте метод query для фильтрации только рангов менее 2.0:

In [129]: df1.query('rnk < 2.0').drop('rnk',1)
Out[129]: 
  col1  col2
0    a     5
1    a     5
2    b    10
4    c    20

Может объединить обе вышеупомянутые команды для получения однострочного решения:

In [130]: df1[df1.groupby('col1')['col2'].rank() < 2]
Out[130]: 
  col1  col2
0    a     5
1    a     5
2    b    10
4    c    20
0 голосов
/ 02 января 2019

другой путь, который я нашел:

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

dfoutput = df1[df1.duplicated(keep=False)].append(df1.sort_values(['col1','col2'],ascending=False).drop_duplicates(['col1']))
dfoutput[~dfoutput.index.duplicated()].sort_index()

    col1    col2
0   a       5
1   a       5
3   b       15
4   c       20
0 голосов
/ 02 января 2019

Начните с сортировки вашего DataFrame в порядке убывания. Затем вычислите две маски: одну для определения, какие строки являются максимальными в их группе, а другую для определения, какие строки дублируются.

Затем мы можем объединить эти маски, чтобы определить, какие строки дублируются и не максимально в своих соответствующих группах, и выполнить один последний этап фильтрации.

v = df1.sort_values('col2', ascending=False)
m1 = v['col2'] == v.groupby('col1', sort=False)['col2'].transform('max')
m2 = v.duplicated('col1')

v[~(m2 & ~m1)].sort_index()   # v[~m2 | m1] - DeMorgan's Law

  col1  col2
0    a     5
1    a     5
3    b    15
4    c    20
...