2014-10-08 3 views
7

Si può eseguire un join sinistro in panda che seleziona solo la prima corrispondenza a destra? Esempio:Si può eseguire un join sinistro in panda che seleziona solo la prima corrispondenza a destra?

left   = pd.DataFrame() 
left['age']  = [11, 12] 
right   = pd.DataFrame() 
right['age'] = [10, 11, 11] 
right['salary'] = [ 100, 150, 200 ] 
left.merge(right, how='left', on='age') 

Returns

age salary 
0 11  100 
1 11  200 
2 12  NaN 

Ma quello che vorrei è quello di preservare il numero di righe di sinistra, semplicemente prendendo la prima partita. Cioè:

age salary 
0 11  100 
2 12  NaN 

Così ho usato

left.merge(right.drop_duplicates(['age']), how='left', on='age') 

ma credo che questo fa una copia completa del diritto. E ha un odore strano.

C'è un modo più elegante?

+1

Questo sarebbe semplice da aggiungere come opzione per "unire", ma al momento non è implementato. – Jeff

+0

Grazie Jeff. Lo chiederò. Lascerà la domanda qui nel caso qualcuno possa indicarmi come evitare la copia (o l'effetto collaterale) nel frattempo. – Quant

risposta

1

Sì, è possibile utilizzare groupby per rimuovere le linee duplicate. Fai tutto ciò che hai fatto per definire sinistra e destra. Ora, io definisco un nuovo dataframe sulla vostra ultima riga:

left2=left.merge(right, how='left', on='age') 
df= left2.groupby(['age'])['salary'].first().reset_index() 
df 

In un primo momento ho usato una .min(), che vi darà il salario minimo ad ogni età, come ad esempio:

df= left2.groupby(['age'])['salary'].min().reset_index() 

Ma ti stavi chiedendo in particolare della prima partita. Per fare ciò usate l'opzione .first(). Nota: .reset_index() alla fine, riformatta di nuovo l'output del groupby in modo da essere un dataframe.