Вычислить средневзвешенное значение с помощью фрейма данных pandas



У меня есть следующий фрейм данных pandas:



data_df = pd.DataFrame({'ind':['la','p','la','la','p','g','g','la'],
'dist':[10.,5.,7.,8.,7.,2.,5.,3.],
'diff':[0.54,3.2,8.6,7.2,2.1,1.,3.5,4.5],
'cas':[1.,2.,3.,4.,5.,6.,7.,8.]})


То есть



    cas  diff  dist ind
0 1 0.54 10 la
1 2 3.20 5 p
2 3 8.60 7 la
3 4 7.20 8 la
4 5 2.10 7 p
5 6 1.00 2 g
6 7 3.50 5 g
7 8 4.50 3 la


Мне нужно вычислить средневзвешенное значение всех столбцов, где веса находятся в столбце "dist", и сгруппировать значения по "ind".

Например для ' ind ' = 'la' и столбца 'diff':



((10*0.54)+(8.60*7)+(7.20*8)+(4.50*3))/(10+7+8+3) = 4.882143


Результат, который я хочу получить, следующий



        cas      diff
ind
g 6.714286 2.785714
la 3.107143 4.882143
p 3.750000 2.558333


Который получается путем умножения каждого значения каждого colums на соответствующее значение в столбце' dist', суммируем результаты с помощью то же самое "ind", а затем деление результата на сумму всех значений "dist", соответствующих одному и тому же ind.



Я думал, что это будет легкая задача, выполняемая методом dataframe 'groupby', но на самом деле это довольно сложно.



Может кто-то пожалуйста, помогите мне?

770   1  

1 ответ:

Вы можете получить внутри групп нормализованные веса , используя transform:

>>> df['weight'] = df['dist'] / df.groupby('ind')['dist'].transform('sum')
>>> df['weight']
0    0.357143
1    0.416667
2    0.250000
3    0.285714
4    0.583333
5    0.285714
6    0.714286
7    0.107143
Name: weight, dtype: float64

Тогда вам просто нужно умножить эти веса на значения и взять сумму:

>>> df['wcas'], df['wdiff'] = (df[n] * df['weight'] for n in ('cas', 'diff'))
>>> df.groupby('ind')[['wcas', 'wdiff']].sum()
         wcas     wdiff
ind                    
g    6.714286  2.785714
la   3.107143  4.882143
p    3.750000  2.558333

Правка: с мутацией на месте:

>>> backup = df.copy()     # make a backup copy to mutate in place
>>> cols = df.columns[:2]  # cas, diff
>>> df[cols] = df['weight'].values[:, None] * df[cols]
>>> df.groupby('ind')[cols].sum()
          cas      diff
ind                    
g    6.714286  2.785714
la   3.107143  4.882143
p    3.750000  2.558333

Comments

    Ничего не найдено.