2015-11-11 3 views
5

Я тэ следующие панд dataframe:Рассчитать средневзвешенную с пандами dataframe

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 '.

Например, для «тх» = «ли» и колонок «дифференциала»:

((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 

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

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

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

ответ

6

Вы можете получить в группах нормированные веса с помощью 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 
+0

Это действительно работает! Спасибо. Единственная проблема заключается в том, что данные, которые я написал, это всего лишь пример, я работаю с большими данными и тысячами столбцов, поэтому я искал решение, в котором мне не нужно записывать имена колонок ... – Cecilia

+0

@ Cecilia вы можете получить список столбцов, используя 'df.columns', и использовать это как в редакции –

+0

Спасибо! Это решение, которое я искал :) – Cecilia

Смежные вопросы