Получите дату окончания путем смещения уникальных значений, используя pandas - PullRequest
1 голос
/ 30 апреля 2020

У меня есть фрейм данных, как показано ниже

df = pd.DataFrame({'subjectID' :[1,1,1,1,1,1,2,2,2],'start_date': 
  ['10/30/2006 08:04','10/30/2006 08:04','11/30/2006 11:01','12/30/2006 02:04','02/13/2007 07:24','04/20/2007 08:34',
   '02/20/2007 06:44','01/20/2007 03:44','11/09/2006 02:03']})

Что я хотел бы сделать, это

1) отсортировать фрейм данных по двум столбцам (subject_id и start_date для каждого предмета). Значение для каждого предмета, дата начала должна быть организована в порядке возрастания. Подобно group by subject_id и отсортируйте значения start_date

2) Заполните столбец end_date для каждого пациента, выбрав следующее уникальное значение start_date для того же пациента.

3) Следуя шагу 2, мы столкнемся с тем, что последняя запись каждого субъекта не будет иметь других значений, выходящих за пределы, поэтому мы просто добавляем 10 дней, чтобы получить дату окончания последней записи для каждого субъекта

Это то, что я пытался

df = df.sort_values(['subjectID', 'start_date'], ascending=[True,True]) # works but is this same as group by and sort after?
df['end_date'] = df.groupby('subjectID')['start_date'].unique().shift(-1) # this doesn't work

Я ожидаю, что мой вывод будет таким, как показано ниже

enter image description here

1 Ответ

1 голос
/ 30 апреля 2020

Использование:

#converting to datetimes
df['start_date'] = pd.to_datetime(df['start_date'])

#sorting
df = df.sort_values(['subjectID', 'start_date'])
#created timestamp for each last value of group and added 10 days
s = df.drop_duplicates('subjectID', keep='last')['start_date'] + pd.Timedelta(10, unit='d')

#shifting without duplicates, added missing values by reindex and forward filling 
df['end_date'] = (df.drop_duplicates(['subjectID','start_date'])
                   .groupby('subjectID')['start_date']
                   .shift(-1)
                   .reindex(df.index)
                   .groupby(df['subjectID'])
                   .ffill()
                   )
#last set last values of groups
df['end_date'].update(s)
print (df)
  subjectID          start_date            end_date
0          1 2006-10-30 08:04:00 2006-11-30 11:01:00
1          1 2006-10-30 08:04:00 2006-11-30 11:01:00
2          1 2006-11-30 11:01:00 2006-12-30 02:04:00
3          1 2006-12-30 02:04:00 2007-02-13 07:24:00
4          1 2007-02-13 07:24:00 2007-04-20 08:34:00
5          1 2007-04-20 08:34:00 2007-04-30 08:34:00
8          2 2006-11-09 02:03:00 2007-01-20 03:44:00
7          2 2007-01-20 03:44:00 2007-02-20 06:44:00
6          2 2007-02-20 06:44:00 2007-03-02 06:44:00
...