Создайте столбец, который помечает, где у другого столбца было условие несколько дней назад

#python #pandas #dataframe

Вопрос:

Я работаю с фреймом данных, в котором мне нужно создать столбец («Newcol»), который будет группироваться по «ColA», а затем для каждой строки — относительно столбца даты («ColB»)…. посмотрите, существовала ли конкретная строка 2 или 3 дня назад до этого значения даты . Пример ниже:

Оригинальный DF:

 ColA ColB ColC  B 2021-10-24 dog  B 2021-10-25 cat  B 2021-10-26 bird  B 2021-10-27 dog  B 2021-10-28 bird  H 2021-10-24 cat  H 2021-10-25 dog  H 2021-10-26 dog  H 2021-10-27 bird  H 2021-10-28 cat  X 2021-10-24 bird  X 2021-10-25 dog  X 2021-10-26 dog  X 2021-10-27 dog  X 2021-10-28 bird  

Итак, скажем, строка для флага — «собака». Группируясь по ColA, мне нужно «NewCol», чтобы использовать столбец даты ColB, оглянитесь на 2-3 дня назад и посмотрите, говорит ли ColC «собака»… если это так, то отметьте это. Таким образом, значения в «NewCol» двоичные: 0 для «нет», 1 для «да». См. Ниже, например:

Желаемый DF:

 ColA ColB ColC NewCol  B 2021-10-24 dog NA  B 2021-10-25 cat NA  B 2021-10-26 bird 1  B 2021-10-27 dog 1  B 2021-10-28 bird 0  H 2021-10-24 cat NA  H 2021-10-25 dog NA  H 2021-10-26 dog 0  H 2021-10-27 bird 1  H 2021-10-28 cat 1  X 2021-10-24 bird NA  X 2021-10-25 dog NA  X 2021-10-26 dog 0  X 2021-10-27 dog 1  X 2021-10-28 bird 1  

Любые предложения приветствуются. Спасибо.

Комментарии:

1. Почему последний ряд B -это 0 ?

2. @QuangHoang последняя строка B-дата = 2021-10-28, таким образом, будут рассмотрены значения ColC за 2-3 дня до (2021-10-25 и 2021-10-26) в ColC, что означает «кошка» и «птица» соответственно… что должно дать 0 в ньюколе

3. А, понятно. Тогда я не думаю, что мое решение отвечает на ваш вопрос. в нем рассматриваются все 3 последних дня.

Ответ №1:

Попробуйте groupby.rolling:

 df['NewCol'] = (df['ColC'].eq('dog')  .groupby(df['ColA']).rolling(3).max()  .reset_index('ColA', drop=True)  )  

Обратите внимание, что это работает только ColB сортируется и последовательно. В противном случае вам нужно установить ColB значение в качестве индекса и '3D' использовать его .

Ответ №2:

Самостоятельное присоединение для получения нового столбца с датами

 extended_df = DF.merge( DF.rename(columns={'ColB':'ColDate'}), on=['ColA', 'ColC'], how='left']  

и определите новый столбец на основе условия

 extended_df['NewCol'] = np.nan   extended_df.loc[ (extended_df.colB - extended_df.ColDate)gt;=2 amp;   (extended_df.colB - extended_df.ColDate)lt;=3 ,   'NewCol' ] = 1  extended_df.loc[ (extended_df.colB - extended_df.ColDate)lt;2 |   (extended_df.colB - extended_df.ColDate)gt;3 ,   'NewCol' ] = 0  

Затем удалите добавленный столбец, чтобы получить окончательный вывод

 df = extended_df.drop( 'ColDate', axis=1 ) del extended_df