Python pandas: удалить дубликаты по столбцам A, сохраняя строку с наивысшим значением в столбце B
У меня есть dataframe с повторяющимися значениями в столбце A. Я хочу сбросить дубликаты, сохраняя строку с самым высоким значением в столбце B.
Итак, это:
A B
1 10
1 20
2 30
2 40
3 10
Должно получиться следующее:
A B
1 20
2 40
3 10
Wes добавил некоторые полезные функции, чтобы сбросить дубликаты: http://wesmckinney.com/blog/?p=340. Но AFAICT, он предназначен для точных дубликатов, поэтому нет упоминаний о критериях выбора строк.
Я предполагаю, что, возможно, это простой способ сделать это - может быть, так же просто, как сортировка данных, прежде чем выпустить дубликаты, но я не знаю, как организовать собственную внутреннюю логику достаточно хорошо, чтобы понять это. Любые предложения?
Ответы
Ответ 1
Это займет последнее. Не максимальный, хотя:
In [10]: df.drop_duplicates(subset='A', keep="last")
Out[10]:
A B
1 1 20
3 2 40
4 3 10
Вы также можете сделать что-то вроде:
In [12]: df.groupby('A', group_keys=False).apply(lambda x: x.loc[x.B.idxmax()])
Out[12]:
A B
A
1 1 20
2 2 40
3 3 10
Ответ 2
Верхний ответ делает слишком много работы и выглядит очень медленным для больших наборов данных. apply
является медленным и его следует избегать, если это возможно. ix
устарел и его следует избегать.
df.sort_values('B', ascending=False).drop_duplicates('A').sort_index()
A B
1 1 20
3 2 40
4 3 10
Или просто группируйте все остальные столбцы и берете максимум необходимого столбца. df.groupby('A', as_index=False).max()
Ответ 3
Попробуйте следующее:
df.groupby(['A']).max()
Ответ 4
Самое простое решение:
Чтобы удалить дубликаты на основе одного столбца:
df = df.drop_duplicates('column_name', keep='last')
Чтобы удалить дубликаты на основе нескольких столбцов:
df = df.drop_duplicates(['col_name1','col_name2','col_name3'], keep='last')
Ответ 5
Вы также можете попробовать это
df.drop_duplicates(subset='A', keep='last')
Я ссылался на это из https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.drop_duplicates.html
Ответ 6
Я думаю, что в вашем случае вам действительно не нужна группа. Я бы сортировал по убыванию вашего столбца B, а затем удалял дубликаты в столбце A, и если вы хотите, у вас также может быть новый приятный и
чистый индекс:
df.sort_values('B', ascending=False).drop_duplicates('A').sort_index().reset_index(drop=True)
Ответ 7
Вот вариант, который я должен был решить, который стоит поделиться: для каждой уникальной строки в columnA
я хотел найти наиболее распространенную связанную строку в columnB
.
df.groupby('columnA').agg({'columnB': lambda x: x.mode().any()}).reset_index()
.any()
выбирает один, если есть связь для режима. (Обратите внимание, что использование .any()
для серии int
возвращает логическое значение, а не выбор одного из них.)
Для исходного вопроса соответствующий подход упрощается до
df.groupby('columnA').columnB.agg('max').reset_index()
.
Ответ 8
Когда уже заданные сообщения отвечают на вопрос, я внес небольшое изменение, добавив имя столбца, к которому применяется функция max() для лучшей читаемости кода.
df.groupby('A', as_index=False)['B'].max()
Ответ 9
это также работает:
a=pd.DataFrame({'A':a.groupby('A')['B'].max().index,'B':a.groupby('A') ['B'].max().values})
Ответ 10
Я не собираюсь дать вам весь ответ (я не думаю, что вы все равно ищете синтаксический анализ и запись в файл), но ключевой намек должен быть достаточным: используйте функцию python set()
, а затем sorted()
или .sort()
в сочетании с .reverse()
:
>>> a=sorted(set([10,60,30,10,50,20,60,50,60,10,30]))
>>> a
[10, 20, 30, 50, 60]
>>> a.reverse()
>>> a
[60, 50, 30, 20, 10]