Группируйте по идентификатору и делите каждый индикатор в группе на значение в первой строке

#python #pandas #pandas-groupby

#python #pandas #pandas-groupby

Вопрос:

Возьмем следующий пример:

 import pandas as pd
import numpy as np

d = {'Group': [1,1,1,2,2,2], 'P': [100,101,96,200,204,208], 'PL': [99,100,94, 199,203,207]}
df = pd.DataFrame(d)
df

    Group   P   PL
0   1      100  99
1   1      101  100
2   1      96   94
3   2      200  199
4   2      204  203
5   2      208  207
 

Для каждой группы в столбце «Группа» я хочу разделить каждый элемент в столбце «PL» на первый элемент в столбце «P». Эти значения будут сохранены в новом столбце

Желаемый результат будет выглядеть следующим образом:

     Group   P    PL   Division
0   1       100  99   0.99
1   1       101  100  1
2   1       96   94   0.94
3   2       200  199  0.995
4   2       204  203  1.015
5   2       208  207  1.035
 

Ответ №1:

Используйте GroupBy.transform со GroupBy.first значениями для групп и делите на Series.div :

 df['Division'] = df['PL'].div(df.groupby('Group')['P'].transform('first'))
print (df)
   Group    P   PL  Division
0      1  100   99     0.990
1      1  101  100     1.000
2      1   96   94     0.940
3      2  200  199     0.995
4      2  204  203     1.015
5      2  208  207     1.035
 

Еще одна идея с map :

 s = df.drop_duplicates('Group').set_index('Group')['P']
df['Division'] = df['PL'].div(df['Group'].map(s)
 

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

1. как строка "first" связана с GroupBy.first ? можете ли вы просто использовать любой метод из объекта GroupBy подобным образом?

2. @SyntaxError — да, вы можете использовать любую функцию из этого , если агрегировать данные. Для не агрегированной функции, как cumsum это не обязательно, тогда используйте df.groupby('Group')['P'].cumsum()