У меня есть фрейм данных с тремя столбцами:
ID Date Status
0 1 1/1/2000 Complete
1 1 1/4/2000 ReOpened
2 1 1/10/2000 ReOpened
3 1 1/11/2000 Closed
4 1 1/15/2000 ReOpened
5 2 1/2/2000 ReOpened
6 2 1/4/2000 ReOpened
7 2 1/10/2000 Closed
8 3 1/20/2000 Closed
9 3 1/22/2000 Closed
10 4 1/25/2000 ReOpened
Для каждого идентификатора, если есть статус «Повторно открыт», мне нужно получить строку, которая показывает первый раз, когда он был «Повторно открыт» на основе даты. Итак, мой вывод будет выглядеть так:
ID ProductionDate Status
0 1 1/4/2000 ReOpened
1 2 1/2/2000 ReOpened
2 4 1/25/2000 ReOpened
Я пытался:
df = pd.np.where(df.Status.str.contains("ReOpened"), df.groupby(['ID']).first(),0)
но это не работает.
Сделайте это с groupby
и cumsum
на маске:
df[df['Status'].eq('ReOpened').groupby(df['ID']).cumsum() == 1]
ID Date Status
1 1 1/4/2000 ReOpened
5 2 1/2/2000 ReOpened
10 4 1/25/2000 ReOpened
Вы также можете использовать groupby
и first
после фильтрации, чтобы получить только первую строку:
df[df['Status'].eq('ReOpened')].groupby('ID', as_index=False).first()
ID Date Status
0 1 1/4/2000 ReOpened
1 2 1/2/2000 ReOpened
2 4 1/25/2000 ReOpened
Если производительность имеет значение, вы можете сократить приведенное выше до одной логической операции индексации с помощью eq
и duplicated
:
df[df['Status'].eq('ReOpened') & ~df.duplicated(['ID', 'Status'])]
ID Date Status
1 1 1/4/2000 ReOpened
5 2 1/2/2000 ReOpened
10 4 1/25/2000 ReOpened
drop_duplicates должно быть достаточно.
df[df.Status.eq('ReOpened')].drop_duplicates(['ID'])
# ID Date Status
#1 1 1/4/2000 ReOpened
#5 2 1/2/2000 ReOpened
#10 4 1/25/2000 ReOpened