удаление чего-либо позже определенной даты

#python #pandas

Вопрос:

 name  date           ID1     check
John  2008-01-01      1       yes        
John  2009-01-01      2       NAN
John  2010-01-01      3       NAN
Cindy 2012-01-01      4       yes
Lisa  2010-01-03      5       yes
Cindy 2010-05-08      6       yes
Lisa  2003-02-03      7       NAN
Lisa  2001-02-01      8       yes
 

У меня есть этот набор данных, который мне нужно немного очистить.

  • Если отметка «да», я буду считать дату самой последней датой и удалю все, что будет после этой даты для каждого человека.
  • Если у одного человека несколько свиданий с отметкой «да», я выбираю самую раннюю дату
  • Подсчитайте ID1 и найдите все, что соответствует предыдущим критериям

Возврат должен выглядеть так:

 name  date           ID1     check
John  2008-01-01      1       yes        
Cindy 2010-05-08      2       yes
Lisa  2001-02-01      3       yes
 

Логика немного слишком сложна, у кого-нибудь есть какие-либо предложения о том, как с этим работать.

Ответ №1:

Это не служба кодирования; поскольку вы не предоставили никакого кода, мы просто удовлетворимся логикой.

Давайте посмотрим на это со стороны «сохранить», а не «удалить». Для вашего приложения логика проще. Кроме того, именно так работает фильтр.

Шаги, которые я вижу, следующие

  1. Фильтр по yes значениям.
  2. groupby name колонна.
  3. Сортировка по дате, по возрастанию.
  4. Сократите каждую группу только до первого элемента (строки). Это простой срез.
  5. Повторите свое ID задание.

Теперь у вас должен быть нужный фрейм данных. Можете ли вы забрать его оттуда?

Ответ №2:

Просто используйте .drop_duplicates(keep='first')

Сначала вы должны отсортировать df, хотя

 df[df['check']=='yes'].sort_values(by=['date']).drop_duplicates(['name', 'check'], keep='first')

    name    date    ID1 check
7   Lisa    2001-02-01  8   yes
0   John    2008-01-01  1   yes
5   Cindy   2010-05-08  6   yes
 

Ответ №3:

Установка:

 df['date'] = pd.to_datetime(df['date'])  # Ensure Date column is datetime
 

Попробуйте удалить строки на основе значений NaN при проверке с помощью dropna

 filtered = df.dropna(subset=['check']).reset_index(drop=True)
 

Затем используйте groupby.transform для подсчета числа ID1 для каждого имени в отфильтрованном кадре.

 filtered['ID1'] = filtered.groupby('name')['ID1'].transform('count')
 

filtered :

     name       date  ID1 check
0   John 2008-01-01    1   yes
1  Cindy 2012-01-01    2   yes
2   Lisa 2010-01-03    2   yes
3  Cindy 2010-05-08    2   yes
4   Lisa 2001-02-01    2   yes
 

Вариант 1: sort_values drop_duplicates

 output = (
    filtered.sort_values('date')  # Make Sure min date is first
        .drop_duplicates('name')  # Remove duplicate name rows (keeping first)
        .sort_index()  # Sort Values by index (Restore order)
)
 

output :

     name       date  ID1 check
0   John 2008-01-01    1   yes
3  Cindy 2010-05-08    2   yes
4   Lisa 2001-02-01    2   yes
 

Вариант 2: groupby.idxmin чтобы получить индексы того, где находятся минимальные значения

 output = filtered.loc[
    filtered.groupby('name')['date'].idxmin()
].sort_index()  # Sort Values by index (Restore order)
 

output :

     name       date  ID1 check
0   John 2008-01-01    1   yes
3  Cindy 2010-05-08    2   yes
4   Lisa 2001-02-01    2   yes