У меня есть фрейм данных pandas, который я хочу выполнить одну и ту же операцию прокрутки для разных групп данных. Рассмотрим следующую df
(см. Нижнюю часть вопроса о коде для построения) с четырьмя столбцами:
id date category target
1 2017-01-01 'a' 0
1 2017-01-01 'b' 0
1 2017-01-21 'a' 1
1 2017-01-21 'b' 1
1 2017-10-01 'a' 0
1 2017-10-01 'b' 0
2 2017-01-01 'a' 1
2 2017-01-01 'b' 1
2 2017-01-21 'a' 0
2 2017-01-21 'b' 0
2 2017-10-01 'a' 0
2 2017-10-01 'b' 0
Мне нужна операция, которая вычисляет логическое значение для каждой пары уникальных идентификаторов-дат, указывающей, является лицелевой столбец 1 в течение 6 месяцев с указанной даты. Поэтому для предоставленного df я бы ожидал результат, который выглядит следующим образом:
id date one_within_6m
1 2017-01-01 True
1 2017-01-21 False
1 2017-10-01 False
2 2017-01-01 False
2 2017-01-21 False
2 2017-10-01 False
Я могу сделать это с помощью цикла for, повторяющегося по строкам и просматривающего 6 месяцев вперед для каждого посещения, но он слишком медленныйиз-за большого размера моего набора данных.
Итак, мне было интересно, можно ли сгруппировать идентификатор по дате и выполнить скользящую операцию с временным окном, чтобы посмотреть на это? Например:
df_grouped = df.groupby(['id', 'date'])
# … do something to set date as index
# ... define some custom function
df_grouped.rolling('6m', on='target').apply(some_custom_function)
Некоторые примечания:
В 6-месячном окне может быть несколько «1», это должно рассматриваться как «Истина» для текущегодата.
В моей голове some_custom_function
проверит, больше ли сумма цели в течение следующих 6 месяцев (исключая текущую дату) больше 1.
Вспомогательный код:
Чтобы создать экземпляр DataFrame, используемый в этом вопросе:
ids = np.concatenate([np.ones(6), np.ones(6)+1])
dates = ['2017-01-01','2017-01-01','2017-01-21','2017-01-21',
'2017-10-01','2017-10-01','2017-01-01','2017-01-01',
'2017-01-21','2017-01-21','2017-10-01','2017-10-01']
categories = ['a','b','a','b','a','b','a','b','a','b','a','b']
targets = [0,0,1,1,0,0,1,1,0,0,0,0]
df = pd.DataFrame({'id':ids,
'date':dates,
'category':categories,
'target':targets})
df['date'] = pd.to_datetime(df['date'])