2017-11-24 1 views
1

Ich habe einen Pandas DatenrahmenPandas neue Datenrahmen aus mehreren Gruppen Erstellen von Operationen

test = pd.DataFrame({'d':[1,1,1,2,2,3,3], 'id':[1,2,3,1,2,2,3], 'v1':[10, 20, 15, 35, 5, 10, 30], 'v2':[3, 4, 1, 6, 0, 2, 0], 'w1':[0.1, 0.3, 0.2, 0.1, 0.4, 0.3, 0.2], 'w2':[0.8, 0.1, 0.2, 0.3, 0.1, 0.1, 0.0]}) 


    d id v1 v2 w1 w2 
0 1 1 10 3 0.10 0.80 
1 1 2 20 4 0.30 0.10 
2 1 3 15 1 0.20 0.20 
3 2 1 35 6 0.10 0.30 
4 2 2 5 0 0.40 0.10 
5 3 2 10 2 0.30 0.10 
6 3 3 30 0 0.20 0.00 

und ich mag einige gewichtete Werte von Gruppe erhalten wie

test['w1v1'] = test['w1'] * test['v1'] 
test['w1v2'] = test['w1'] * test['v2'] 
test['w2v1'] = test['w2'] * test['v1'] 
test['w2v2'] = test['w2'] * test['v2'] 

Wie kann ich das Ergebnis gut erhalten in ein df. etwas, das

test.groupby('id').sum()['w1v1']/test.groupby('id').sum()['w1'] 

id 
1 22.50 
2 11.00 
3 22.50 

sondern umfasst Spalten für jeden gewichteten Wert, so wie

id w1v1 w1v2 w2v1 w2v2 
1 22.50 ... ... ... 
2 11.00 ... ... ... 
3 22.50 ... ... ... 

Irgendwelche Ideen wie

sieht, wie ich dies schnell und einfach erreichen können?

Antwort

1

Verwendung:

cols = ['w1v1','w1v2','w2v1','w2v2'] 
test1 = (test[['w1', 'w2', 'w1', 'w2']] * test[['v1', 'v1', 'v2', 'v2']].values) 
test1.columns = cols 
print (test1) 
    w1v1 w1v2 w2v1 w2v2 
0 1.0 8.0 0.3 2.4 
1 6.0 2.0 1.2 0.4 
2 3.0 3.0 0.2 0.2 
3 3.5 10.5 0.6 1.8 
4 2.0 0.5 0.0 0.0 
5 3.0 1.0 0.6 0.2 
6 6.0 0.0 0.0 0.0 

df = test.join(test1).groupby('id').sum() 
df1 = df[cols]/df[['w1', 'w2', 'w1', 'w2']].values 
print (df1) 
    w1v1  w1v2 w2v1  w2v2 
id         
1 22.5 16.818182 4.5 3.818182 
2 11.0 11.666667 1.8 2.000000 
3 22.5 15.000000 0.5 1.000000 

Eine weitere dynamische Lösung mit MultiIndex DataFrame s:

a = ['v1', 'v2'] 
b = ['w1', 'w2'] 
mux = pd.MultiIndex.from_product([a,b]) 

df1 = test.set_index('id').drop('d', axis=1) 
v = df1.reindex(columns=mux, level=0) 
w = df1.reindex(columns=mux, level=1) 

print (v) 
    v1  v2 
    w1 w2 w1 w2 
id    
1 10 10 3 3 
2 20 20 4 4 
3 15 15 1 1 
1 35 35 6 6 
2 5 5 0 0 
2 10 10 2 2 
3 30 30 0 0 

print (w) 
    v1  v2  
    w1 w2 w1 w2 
id      
1 0.1 0.8 0.1 0.8 
2 0.3 0.1 0.3 0.1 
3 0.2 0.2 0.2 0.2 
1 0.1 0.3 0.1 0.3 
2 0.4 0.1 0.4 0.1 
2 0.3 0.1 0.3 0.1 
3 0.2 0.0 0.2 0.0 

df = w * v 
print (df) 
    v1   v2  
    w1 w2 w1 w2 
id      
1 1.0 8.0 0.3 2.4 
2 6.0 2.0 1.2 0.4 
3 3.0 3.0 0.2 0.2 
1 3.5 10.5 0.6 1.8 
2 2.0 0.5 0.0 0.0 
2 3.0 1.0 0.6 0.2 
3 6.0 0.0 0.0 0.0 

df1 = df.groupby('id').sum()/w.groupby('id').sum() 
#flatten MultiIndex columns 
df1.columns = ['{0[1]}{0[0]}'.format(x) for x in df1.columns] 
print (df1) 
    w1v1  w2v1 w1v2  w2v2 
id         
1 22.5 16.818182 4.5 3.818182 
2 11.0 11.666667 1.8 2.000000 
3 22.5 15.000000 0.5 1.000000 
0

Wenn Sie Multi Indexspalte nehmen können, können Sie groupby + dot verwenden:

test.groupby('id').apply(
    lambda g: g.filter(like='v').T.dot(g.filter(like='w')/g.filter(like='w').sum()).stack() 
) 

#  v1    v2   
#  w1   w2 w1  w2 
#id         
#1 22.5 16.818182 4.5 3.818182 
#2 11.0 11.666667 1.8 2.000000 
#3 22.5 15.000000 0.5 1.000000 
Verwandte Themen