sql max() над (разделением по) в pandas

#python-3.x #pandas

#python-3.x #pandas

Вопрос:

Я пытаюсь получить тот же вывод SQL для max через раздел by, но в pandas. цель состоит в том, чтобы заменить did_renew==No на Yes, но при определенных условиях и для группы фрейма данных Это мой поток данных:

         date_id               sf_id renewal_date is_up_for_renewal     did_renew  datediff
168  2020-09-01  0010O00001n1s1rQAA  2020-09-30   Yes               Undetermined NaN      
169  2020-08-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
170  2020-07-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
171  2020-06-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
172  2020-05-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
173  2020-04-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
174  2020-03-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
175  2020-02-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
176  2020-01-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
177  2019-12-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
178  2019-11-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
179  2019-10-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0     
180  2019-08-01  0010O00001n1s1rQAA  2019-08-31   Yes               No            2.0     
181  2019-07-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
182  2019-06-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
183  2019-05-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
184  2019-04-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
185  2019-03-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
186  2019-02-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
187  2019-01-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
188  2018-12-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
189  2018-11-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
190  2018-10-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
191  2018-09-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
192  2018-08-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0     
    
  

В SQL я бы написал: случай, когда dafediff= 2, тогда max (‘Yes’) над (разделом по sf_id, renewal_date) заканчивается
Это создало бы новый столбец со значениями только для строк 180-192 (см. Дата обновления отличается для строк 168-179, 180-192)
Вот как результаты должны быть в столбце target :

         date_id               sf_id renewal_date is_up_for_renewal     did_renew  datediff        target
168  2020-09-01  0010O00001n1s1rQAA  2020-09-30   Yes               Undetermined NaN        Undetermined
169  2020-08-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
170  2020-07-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
171  2020-06-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
172  2020-05-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
173  2020-04-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
174  2020-03-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
175  2020-02-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
176  2020-01-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
177  2019-12-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
178  2019-11-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
179  2019-10-01  0010O00001n1s1rQAA  2020-09-30   No                Undetermined  1.0       Undetermined
180  2019-08-01  0010O00001n1s1rQAA  2019-08-31   Yes               No            2.0       Yes         
181  2019-07-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
182  2019-06-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
183  2019-05-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
184  2019-04-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
185  2019-03-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
186  2019-02-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
187  2019-01-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
188  2018-12-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
189  2018-11-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
190  2018-10-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
191  2018-09-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         
192  2018-08-01  0010O00001n1s1rQAA  2019-08-31   No                No            1.0       Yes         

  

Полный фрейм данных будет включать множество групп sf_id, поэтому я знаю, что мне нужно использовать метод groupby для [sf_id,renewal_date] , но не уверен, как это сделать
Заранее спасибо!

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

1. Я не понял, каким должен быть ожидаемый результат, но если у него есть функция, очень похожая на SQL over в pandas, это transform

2. Я отредактировал свой вопрос, чтобы показать целевой столбец, если это поможет

Ответ №1:

IIUC,

 df['target'] = (df.assign(target=df['datediff']==2))
                  .groupby(['sf_id', 'renewal_date'])['target']
                  .transform('max').map({True:'Yes',False:'Undetermined'})
  

Вывод:

         date_id               sf_id renewal_date is_up_for_renewal     did_renew  datediff        target
168  2020-09-01  0010O00001n1s1rQAA   2020-09-30               Yes  Undetermined       NaN  Undetermined
169  2020-08-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
170  2020-07-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
171  2020-06-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
172  2020-05-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
173  2020-04-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
174  2020-03-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
175  2020-02-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
176  2020-01-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
177  2019-12-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
178  2019-11-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
179  2019-10-01  0010O00001n1s1rQAA   2020-09-30                No  Undetermined       1.0  Undetermined
180  2019-08-01  0010O00001n1s1rQAA   2019-08-31               Yes            No       2.0           Yes
181  2019-07-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
182  2019-06-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
183  2019-05-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
184  2019-04-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
185  2019-03-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
186  2019-02-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
187  2019-01-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
188  2018-12-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
189  2018-11-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
190  2018-10-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
191  2018-09-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
192  2018-08-01  0010O00001n1s1rQAA   2019-08-31                No            No       1.0           Yes
  

Подробности, очень похожие на ваш случай, когда я создаю / assign временный столбец ‘target’, который является истинным, когда datediff равен 2. Затем я перейду к groupby этому столбцу точно так же, как к вашему разделу by, используя ‘sf_id’ и ‘renewal_date’. Затем мы используем transform , чтобы получить максимальную «цель» для этой группы, следовательно, создаем True для всех записей в группе, где любая запись имеет datediff, равный 2. Наконец, мы используем map , чтобы изменить True на Yes и False на Undetermined.

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

1. @nimi1234 Всегда пожалуйста. Удачного кодирования. Будьте в безопасности и оставайтесь здоровыми.