Мне нужно проанализировать последние 60 дней до последней даты, когда каждый пользователь был активным.
Мой фрейм данных содержит даты ('CalendarDate'), когда каждый пользователь ('DataSourceId') был активным ('Activity'целое число) - одна строка на дату.Я сгруппировал фрейм данных по DataSourceId, поэтому у меня есть даты в столбцах, и я взял последний день, когда каждый пользователь был активен 'max_date':
df['max_date'] = df.groupby('DataSourceId')['CalendarDate'].transform('max')
Данные выглядят примерно так, хотя 'CalendarDate' и 'max_date 'на самом деле datetime64[ns]
формат (значения Activity float64
):
ID Jan1 Jan2 Jan3 Jan4 Jan5... max_date
1 8 15 10 Jan5
2 2 13 Jan3
3 6 11 Jan2
Теперь я хочу перестроить столбцы из календарных дат в "последние x дней" для каждой строки.Например:
ID Last Last-1 Last-2 Last-3 ... Last-x
1 10 15 8
2 13 2
3 11 6
Мне не удалось найти никаких примеров подобных преобразований, и я действительно застрял здесь.
РЕДАКТИРОВАНИЕ: После адаптации решения Jezrael я заметилиногда это не удавалось.
Я думаю, что проблема связана с этим кодом в решении jezrael: r = data_wide.bfill().isna().sum(axis=1).values
Пример: эти данные не выполняются (и r = [0 3]
):
CalendarDate 2017-07-02 2017-07-03 2017-07-06 2017-07-07 2017-07-08 2017-07-09
DataSourceId
1000648 NaN 188.37 178.37 NaN 128.37 18.37
1004507 51.19 NaN 52.19 53.19 NaN NaN
В частности, перестроенный фрейм данных выглядит следующим образом:
Last-0 Last-1 Last-2 Last-3 Last-4 Last-5
DataSourceId
1000648 18.37 128.37 NaN 178.37 188.37 NaN
1004507 52.19 NaN 51.19 NaN NaN 53.19
Если я изменяю порядок в фрейме данных, меняя идентификатор 1000648 на 1100648 (чтобы он стал второй строкой), это результат (r = [0 2]
):
Last-0 Last-1 Last-2 Last-3 Last-4 Last-5
DataSourceId
1004507 NaN NaN 53.19 52.19 NaN 51.19
1100648 NaN 178.37 188.37 NaN 18.37 128.37