2015-11-11 9 views
5

Ich habe folgende te Pandas Datenrahmen:berechnen gewichteter Durchschnitt mit Pandas Datenrahmen

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.]}) 

, das ist

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 

ich den gewichteten Durchschnitt aller Spalten berechnen müssen, wobei die Gewichte in der ' dist 'spalte und gruppiere die Werte mit' ind '.

beispielsweise für 'ind' = 'la' und dem 'diff' Säule:

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

Das Ergebnis I ist die folgende

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

erhalten wollen, die durch Multiplizieren jedes erhaltene Wert jeder Spalte durch den entsprechenden Wert in der 'dist'-Spalte, summiere die Ergebnisse mit dem gleichen' ind 'und dividiere dann das Ergebnis durch die Summe aller' dist'-Werte, die der gleichen ind entsprechen.

Ich dachte, das wäre eine einfache Aufgabe gewesen, die von der Dataframe-Methode "groupby" erledigt wurde, aber eigentlich ist es ziemlich kompliziert.

Kann mir bitte jemand helfen?

Antwort

6

können Sie erhalten innerhalb von Gruppen normalisierten Gewichte von transform mit:

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

Dann müssen Sie nur dieses Gewicht multiplizieren mit den Werten, und nehmen Sie die Summe:

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

Edit: mit In-Place-Mutation:

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

Dies funktioniert tatsächlich! Vielen Dank. Das einzige Problem ist, dass der Datenrahmen, den ich geschrieben habe, nur ein Beispiel ist, ich arbeite mit großen Daten und Tausenden von Spalten, also suchte ich nach einer Lösung, bei der ich die Spaltennamen nicht aufschreiben muss ... – Cecilia

+0

@ Cecilia Sie können eine Liste von Spalten mit 'df.columns' erhalten, und verwenden Sie das wie in der Bearbeitung –

+0

Vielen Dank !!! Dies ist die Lösung, die ich suchte :) – Cecilia