2013-05-16 14 views
7

Voglio unire due dataframes su colonne specifiche (key1, key2) e riassumere i valori per un'altra colonna (valore).unione di 2 frame di dati in Panda: join su alcune colonne, somma di altri

>>> df1 = pd.DataFrame({'key1': range(4), 'key2': range(4), 'value': range(4)}) 
    key1 key2 value 
0  0  0  0 
1  1  1  1 
2  2  2  2 
3  3  3  3 

>>> df2 = pd.DataFrame({'key1': range(2, 6), 'key2': range(2, 6), 'noise': range(2, 6), 'value': range(10, 14)}) 
    key1 key2 noise value 
0  2  2  2  10 
1  3  3  3  11 
2  4  4  4  12 
3  5  5  5  13 

voglio che questo risultato:

key1 key2 value 
0  0  0  0 
1  1  1  1 
2  2  2  12 
3  3  3  14 
4  4  4  12 
5  5  5  13 

In termini di SQL, voglio:

SELECT df1.key1, df1.key2, df1.value + df2.value AS value 
FROM df1 OUTER JOIN df2 ON key1, key2 

Ho provato due approcci:

approccio 1

concatenated = pd.concat([df1, df2]) 
grouped = concatenated.groupby(['key1', 'key2'], as_index=False) 
summed = grouped.agg(np.sum) 
result = summed[['key1', 'key2', 'value']] 

approccio 2

joined = pd.merge(df1, df2, how='outer', on=['key1', 'key2'], suffixes=['_1', '_2']) 
joined = joined.fillna(0.0) 
joined['value'] = joined['value_1'] + joined['value_2'] 
result = joined[['key1', 'key2', 'value']] 

Entrambi gli approcci danno il risultato che voglio, ma mi chiedo se c'è un modo più semplice.

risposta

8

Io non so più semplice, ma è possibile ottenere un po 'più conciso:

>>> pd.concat([df1, df2]).groupby(["key1", "key2"], as_index=False)["value"].sum() 
    key1 key2 value 
0  0  0  0 
1  1  1  1 
2  2  2  12 
3  3  3  14 
4  4  4  12 
5  5  5  13 

seconda della vostra tolleranza per il concatenamento ops, si potrebbe desiderare di rompere questo su più righe in ogni caso, anche se (a quattro tende ad essere vicino al mio limite superiore, in questo caso concat-groupby-select-sum).

+0

Sembra * come * dovrebbe essere un modo più conciso ... come un'aggregazione di unione. –

+0

Stavo cercando una funzione magica che faccia tutto in modo ottimizzato. – Laurie

+0

Ho scelto l'approccio 2 e incatenato gli op il più possibile perché è più veloce in questo modo. – Laurie

Problemi correlati