#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:
Это не служба кодирования; поскольку вы не предоставили никакого кода, мы просто удовлетворимся логикой.
Давайте посмотрим на это со стороны «сохранить», а не «удалить». Для вашего приложения логика проще. Кроме того, именно так работает фильтр.
Шаги, которые я вижу, следующие
- Фильтр по
yes
значениям. groupby
name
колонна.- Сортировка по дате, по возрастанию.
- Сократите каждую группу только до первого элемента (строки). Это простой срез.
- Повторите свое
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