2017-05-13 13 views
1

私は以下のようなデータフレームを持っていますパンダのデータフレーム内の複数の列の加重平均

クラス|学生| V1 | V2 | V3 | wb

A |マックス| 10 | 12 | 14 | 1

A |アン| 9 | 6 | 7 | 0.9

B |トム| 6 | 7 | 10 | 0.3

B |ディック| 3 | 8 | 7 | 0.7

C | Dibs | 5 | 2 | 3 | 0.8

C |モック| 6 | 4 | 3 | 0.6

D |サニー| 3 | 4 | 5 | 0.9

D |ロック| 8 | 3 | 6 | 1

と私はクラス でグループ化されたV1、V2、V3結果は

クラスV1_M V2_M V3_M

以下のようなものでなければなりませんの加重平均を計算したいですB 5 3 3

C 4 4 3

これまでのところ、私は、各列のデータフレームを分離することができます。しかし、私はパンダの経験の1週間で初心者です、私は非常に非効率的 を感じるそして、ここで1変数

import pandas as pd 
import numpy as np 

def wtdavg(frame, var, wb): 
    d = frame[var] 
    w = frame[wb] 
    return (d * w).sum()/w.sum() 

df = pd.read_csv('Sample.csv') 
Matrix = df.groupby(['Class']).apply(wtdavg,var='V2',wb='wb') 
print(Matrix) 

ためのコードです。前もって感謝します。

マックス

答えて

0
#use apply to calculate weighted mean for alll 3 columns in one go. 
df2 = df.groupby('Class').apply(lambda x: pd.Series([sum(x.V1*x.wb)/sum(x.wb), sum(x.V2*x.wb)/sum(x.wb), sum(x.V3*x.wb)/sum(x.wb)])) 
#rename columns 
df2.columns=['V1_M','V2_M','V3_M'] 

df2 
Out[858]: 
      V1_M  V2_M  V3_M 
Class        
A  9.526316 9.157895 10.684211 
B  3.900000 7.700000 7.900000 
C  5.428571 2.857143 3.000000 
D  5.631579 3.473684 5.526316 

更新

#put all your variable names in a list (can be copied over from df.columns) 
var_cols = ['V1', 'V2', 'V3'] 
df2 = df.groupby('Class').apply(lambda x: pd.Series([sum(x[v*x.wb)/sum(x.wb) for v in var_cols])) 
df2.columns = [e+'_M' for e in var_cols] 
      V1_M  V2_M  V3_M 
Class        
A  9.526316 9.157895 10.684211 
B  3.900000 7.700000 7.900000 
C  5.428571 2.857143 3.000000 
D  5.631579 3.473684 5.526316 
+0

ありがとうございました。もし100sの変数があれば?私たちはlambda xのダイナミックなシリーズを持つことができますか?pd.Series([sum(x.V1 * x.wb)/ sum(x.wb)......... v1000まで) – mAx

+0

@mAxは、私の更新を見てください。 – Allen

+0

ありがとうございました...それは完全に働きました。
df2 = df.groupby( 'Class')。適用(ラムダx:pd.Series([x [v] * x.wb)/合計(x。wb)for v in var_cols])) – mAx

0
import pandas as pd 
import numpy as np 

def wtdavg(frame, var, wb): 
    d = frame[var] 
    w = frame[wb] 
    return (d * w).sum()/w.sum() 

df = pd.read_csv('Sample.csv') 
temp_df = pd.DataFrame() 
for column in df.columns: 
    if df[column].dtype == np.int64: 
     temp_S = pd.DataFrame(df[column].groupby(df['Class']).mean()) 
     frames = [temp_df, temp_S] 
     temp_df = pd.concat(frames, axis = 'columns') 
print temp_df 
+0

meanの代わりにwtdavgを適用しようとしましたが、値が間違っています。それのためのサンプルがありますか? – mAx

1

より一般的な解決策:

1.ItはStudentせずにすべての列の加重平均を作成し、Class

df2 = df.drop('Student', axis=1) \ 
     .groupby('Class') \ 
     .apply(lambda x: x.drop(['Class', 'wb'], axis=1).mul(x.wb, 0).sum()/(x.wb).sum()) \ 
     .add_suffix('_M') \ 
     .reset_index() 
print (df2) 
    Class  V1_M  V2_M  V3_M 
0  A 9.526316 9.157895 10.684211 
1  B 3.900000 7.700000 7.900000 
2  C 5.428571 2.857143 3.000000 
3  D 5.631579 3.473684 5.526316 

それとも、加重平均の列を定義することができます。

df2 = df.groupby('Class') \ 
     .apply(lambda x: x[['V1', 'V2', 'V3']].mul(x.wb, 0).sum()/(x.wb).sum()) \ 
     .add_suffix('_M') \ 
     .reset_index() 
print (df2) 
    Class  V1_M  V2_M  V3_M 
0  A 9.526316 9.157895 10.684211 
1  B 3.900000 7.700000 7.900000 
2  C 5.428571 2.857143 3.000000 
3  D 5.631579 3.473684 5.526316 

より一般的には、フィルタであるすべての列がfilterによってVで始まる:

df2 = df.groupby('Class') \ 
     .apply(lambda x: x.filter(regex='^V').mul(x.wb, 0).sum()/(x.wb).sum()) \ 
     .add_suffix('_M') \ 
     .reset_index() 
print (df2) 
    Class  V1_M  V2_M  V3_M 
0  A 9.526316 9.157895 10.684211 
1  B 3.900000 7.700000 7.900000 
2  C 5.428571 2.857143 3.000000 
3  D 5.631579 3.473684 5.526316 
関連する問題