Как создать столбец на основе условий в других строках — Pandas Dataframe?

#pandas #dataframe #reshape #data-manipulation

#pandas #dataframe #изменить форму #манипулирование данными

Вопрос:

У меня следующая проблема :

Фрейм данных с именем df1 выглядит следующим образом :

     Id      PVF PM_year Year
0   A6489   75  25      2018
1   A175    56  54      2018
2   A2856   34  65      2018
3   A6489   35  150     2019
4   A175    45  700     2019
5   A2856   55  120     2019
6   A6489   205 100     2020
7   A2856   35  445     2020
 

Я хочу создать новый столбец с именем PM_previous_year, который для каждой комбинации (ID Year) равен значению PM_year того же идентификатора и предыдущего года…

Пример :

Для строки с индексом 3 идентификатор равен ‘A6489’, а год — 2019. Таким образом, значение нового столбца «PM_previous_year» должно быть значением строки, где идентификатор тот же (‘A6489’), а год равен 2018 (2019-1). в этом простом примере он соответствует строке с индексом 0, а ожидаемое значение для нового столбца в строке с индексом 3 равно 25.

Наконец, целевой фрейм данных df2 для этого короткого примера выглядит следующим образом :

     Id     PVF  PM_year Year    PM_previous_year
0   A6489   75  25      2018    NaN
1   A175    56  54      2018    NaN
2   A2856   34  65      2018    NaN
3   A6489   35  150     2019    25.0
4   A175    45  700     2019    54.0
5   A2856   55  120     2019    65.0
6   A6489   205 100     2020    150.0
7   A2856   35  445     2020    120.0
 

Я пока не нашел никакого очевидного решения. Может быть, есть способ изменить форму df, но я не очень хорошо знаком с этим.
Если у кого-нибудь есть какие-либо идеи, я был бы очень благодарен.
Спасибо

Ответ №1:

Если возможно, упростите решение и перенос PM_year для каждого Id использования:

 df['PM_previous_year'] = df.groupby('Id')['PM_year'].shift()
print (df)
      Id  PVF  PM_year  Year  PM_previous_year
0  A6489   75       25  2018               NaN
1   A175   56       54  2018               NaN
2  A2856   34       65  2018               NaN
3  A6489   35      150  2019              25.0
4   A175   45      700  2019              54.0
5  A2856   55      120  2019              65.0
6  A6489  205      100  2020             150.0
7  A2856   35      445  2020             120.0
 

Или:

 s = df.pivot('Year','Id','PM_year').shift().unstack().rename('PM_previous_year')

df = df.join(s, on=['Id','Year'])
print (df)
      Id  PVF  PM_year  Year  PM_previous_year
0  A6489   75       25  2018               NaN
1   A175   56       54  2018               NaN
2  A2856   34       65  2018               NaN
3  A6489   35      150  2019              25.0
4   A175   45      700  2019              54.0
5  A2856   55      120  2019              65.0
6  A6489  205      100  2020             150.0
7  A2856   35      445  2020             120.0
 

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

1. Отлично!! Большое спасибо за ваш ответ «в реальном времени». Это работает отлично.