#python #python-3.x #pandas #dataframe
Вопрос:
У меня есть df,вы можете получить его, скопировав этот код:
from io import StringIO df = """ RateCompany gs RB ValIssueDate 115 T G 54 19580101 116 T G 54 19870101 336 T S 54 19580101 337 T S 54 19870101 338 T j 53 19970101 """ df = pd.read_csv(StringIO(df.strip()), sep='s ')
Теперь я хочу удалить все строки с одинаковыми показателями компании,gs,RB ,но значение ValIssueDate больше, чем в другой строке.
Результат должен быть:
RateCompany gs RB ValIssueDate 115 T G 54 19580101 336 T S 54 19580101 338 T j 53 19970101
Кто-нибудь из друзей может помочь?
Ответ №1:
Сортировка по столбцам, которые вы хотите сравнить, затем отбросьте дубликаты по ключевым столбцам:
df.sort_values('ValIssueDate').drop_duplicates(['RateCompany', 'gs', 'RB'])
Выход:
RateCompany gs RB ValIssueDate 115 T G 54 19580101 336 T S 54 19580101 338 T j 53 19970101
Комментарии:
1. Большое вам спасибо за ваш ответ ,но я думаю ,что этот метод недостаточно безопасен, потому что он всегда будет отбрасывать вторую строку, если я изменю порядок строк, он не будет работать.
2. @William —
sort_values
устанавливает порядок по мере необходимости, прежде чем удалять дубликаты. Этот ответ будет работать независимо от порядка ваших строк.3. @Уильям, ты уверен?
4. просто любопытно, что значения sort_ всегда будут иметь меньшее значение по умолчанию ?
5. @Уильям да, есть опция
ascending
, значение которой по умолчаниюTrue
равно .
Ответ №2:
Вот еще один способ использования idxmin()
df.loc[df.groupby(['RateCompany', 'gs', 'RB'])['ValIssueDate'].idxmin()] RateCompany gs RB ValIssueDate 115 T G 54 19580101 336 T S 54 19580101 338 T j 53 19970101
Комментарии:
1. Большое вам спасибо за ваш ответ ,и он работает ,но не самый быстрый ,еще раз спасибо.
2. @William это может быть быстрее для больших наборов данных, сортировка не нужна и имеет меньшую временную сложность. Если вас интересует только одна строка, сортировка обычно является ненужным запахом кода.
Ответ №3:
Вы могли бы использовать groupby
с min
:
gt;gt;gt; df.groupby(["RateCompany", "gs", "RB"], as_index=False)["ValIssueDate"].min() RateCompany gs RB ValIssueDate 0 T G 54 19580101 1 T S 54 19580101 2 T j 53 19970101
Комментарии:
1. Большое вам спасибо за ваш ответ ,и он работает ,но не самый быстрый ,еще раз спасибо.