Qual'è la differenza tra join e merge in Pandas?


208

Supponiamo che io abbia due DataFrames in questo modo:

left = pd.DataFrame({'key1': ['foo', 'bar'], 'lval': [1, 2]})

right = pd.DataFrame({'key2': ['foo', 'bar'], 'rval': [4, 5]})

Voglio unirli, quindi provo qualcosa del genere:

pd.merge(left, right, left_on='key1', right_on='key2')

E sono felice

    key1    lval    key2    rval
0   foo     1       foo     4
1   bar     2       bar     5

Ma sto cercando di utilizzare il metodo join, che mi è stato portato a credere sia abbastanza simile.

left.join(right, on=['key1', 'key2'])

E ottengo questo:

//anaconda/lib/python2.7/site-packages/pandas/tools/merge.pyc in _validate_specification(self)
    406             if self.right_index:
    407                 if not ((len(self.left_on) == self.right.index.nlevels)):
--> 408                     raise AssertionError()
    409                 self.right_on = [None] * n
    410         elif self.right_on is not None:

AssertionError: 

Cosa mi sto perdendo?


4
Il problema specifico qui è che mergeunisce le colonne leftalle colonne di right, che è quello che vuoi, ma join(... on=[...])unisce le colonne lefta cui indicizzare le chiavi right, che non è quello che vuoi. Vedi la mia risposta di seguito per maggiori dettagli.
Matthias Fripp,

3
DataFrame.join () vuole sempre far corrispondere gli indici o le chiavi del chiamante (specificato ondall'opzione) con gli otherindici dell '. Ricorda, indici per join. Mentre merge () è un metodo più generico.
Jiapeng Zhang,

Risposte:


87

Uso sempre joinsugli indici:

import pandas as pd
left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]}).set_index('key')
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]}).set_index('key')
left.join(right, lsuffix='_l', rsuffix='_r')

     val_l  val_r
key            
foo      1      4
bar      2      5

La stessa funzionalità può essere ottenuta utilizzando mergele seguenti colonne:

left = pd.DataFrame({'key': ['foo', 'bar'], 'val': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'val': [4, 5]})
left.merge(right, on=('key'), suffixes=('_l', '_r'))

   key  val_l  val_r
0  foo      1      4
1  bar      2      5

L'errore sembra dire che si aspetta che il multiindice rightabbia la stessa profondità della lunghezza attiva on. Questo ha senso per me in un certo senso. Posso accettare che la semantica è diversa. Ma vorrei sapere se riesco a ottenere lo stesso comportamento con df.join
munk

346

pandas.merge() è la funzione sottostante utilizzata per tutti i comportamenti di unione / unione.

DataFrames fornisce i metodi pandas.DataFrame.merge()e pandas.DataFrame.join()come un modo conveniente per accedere alle funzionalità di pandas.merge(). Ad esempio, df1.merge(right=df2, ...)equivale a pandas.merge(left=df1, right=df2, ...).

Queste sono le principali differenze tra df.join()e df.merge():

  1. cerca nella tabella a destra: df1.join(df2)si unisce sempre tramite l'indice di df2, ma df1.merge(df2)può unirsi a una o più colonne di df2(impostazione predefinita) o all'indice di df2(con right_index=True).
  2. cerca nella tabella di sinistra: per impostazione predefinita, df1.join(df2)utilizza l'indice di df1e df1.merge(df2)usa le colonne di df1. Questo può essere ignorato specificando df1.join(df2, on=key_or_keys)o df1.merge(df2, left_index=True).
  3. left vs inner join: df1.join(df2)esegue un join sinistro per impostazione predefinita (mantiene tutte le righe di df1), ma df.mergeesegue un join interno per impostazione predefinita (restituisce solo le righe corrispondenti di df1e df2).

Quindi, l'approccio generico è usare pandas.merge(df1, df2)o df1.merge(df2). Ma per una serie di situazioni comuni (mantenendo tutte le righe df1e unendole a un indice df2), è possibile salvare un po 'di battitura usando df1.join(df2)invece.

Alcune note su questi argomenti dalla documentazione su http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging :

merge è una funzione nello spazio dei nomi dei panda ed è anche disponibile come metodo di istanza DataFrame, con il DataFrame chiamante considerato implicitamente l'oggetto sinistro nel join.

Il DataFrame.joinmetodo correlato , utilizza mergeinternamente per i join index-on-index e index-on-column (s), ma si unisce agli indici per impostazione predefinita anziché tentare di unirsi su colonne comuni (il comportamento predefinito per merge). Se ti unisci all'indice, potresti voler utilizzare DataFrame.joinper salvare te stesso un po 'di battitura.

...

Queste due chiamate di funzione sono completamente equivalenti:

left.join(right, on=key_or_keys)
pd.merge(left, right, left_on=key_or_keys, right_index=True, how='left', sort=False)

19
Questa dovrebbe essere sicuramente la risposta accettata! Grazie per la spiegazione approfondita
Yohan Obadia,

@Matthias Fripp, forse per i più esperti è ovvio, ma si potrebbe anche dire che "la ricerca nella tabella a destra: df1.join (df2) può essere sovrascritta a df1.join (df2, on = key_or_keys?
spacedustpi

@spacedustpi, penso che tu stia dicendo che puoi usare on=key_or_keysper cambiare il modo in cui le righe si trovano nella tabella giusta. Tuttavia, in realtà non è così. L' onargomento modifica la ricerca nella tabella di sinistra ( df1) dall'indice alle colonne. Tuttavia, anche con questo argomento, la tabella giusta ( df2) verrà abbinata tramite il suo indice. (Vedi l'ultimo esempio sopra.)
Matthias Fripp,

Panda ha diversi metodi per affrontare queste situazioni, tra cui unire, unire, aggiungere, concatare, combinare, combinare per primo. Dai un'occhiata a ciascuno di questi per avere un'idea di quale sarebbe la soluzione migliore per la tua situazione
xiaxio

13

Credo che join()sia solo un metodo pratico. Prova df1.merge(df2)invece, che ti consente di specificare left_one right_on:

In [30]: left.merge(right, left_on="key1", right_on="key2")
Out[30]: 
  key1  lval key2  rval
0  foo     1  foo     4
1  bar     2  bar     5

11

Da questa documentazione

Panda fornisce una singola funzione, unione, come punto di ingresso per tutte le operazioni standard di unione del database tra gli oggetti DataFrame:

merge(left, right, how='inner', on=None, left_on=None, right_on=None,
      left_index=False, right_index=False, sort=True,
      suffixes=('_x', '_y'), copy=True, indicator=False)

E :

DataFrame.joinè un metodo conveniente per combinare le colonne di due DataFrame potenzialmente indicizzati in modo diverso in un DataFrame a singolo risultato. Ecco un esempio molto semplice: l'allineamento dei dati qui è sugli indici (etichette delle righe). Questo stesso comportamento può essere ottenuto utilizzando l'unione più argomenti aggiuntivi che indicano come utilizzare gli indici:

result = pd.merge(left, right, left_index=True, right_index=True,
how='outer')

8

Una delle differenze è che mergesta creando un nuovo indice e joinsta mantenendo l'indice sul lato sinistro. Può avere una grande conseguenza sulle trasformazioni successive se si assume erroneamente che l'indice non sia cambiato con merge.

Per esempio:

import pandas as pd

df1 = pd.DataFrame({'org_index': [101, 102, 103, 104],
                    'date': [201801, 201801, 201802, 201802],
                    'val': [1, 2, 3, 4]}, index=[101, 102, 103, 104])
df1

       date  org_index  val
101  201801        101    1
102  201801        102    2
103  201802        103    3
104  201802        104    4

-

df2 = pd.DataFrame({'date': [201801, 201802], 'dateval': ['A', 'B']}).set_index('date')
df2

       dateval
date          
201801       A
201802       B

-

df1.merge(df2, on='date')

     date  org_index  val dateval
0  201801        101    1       A
1  201801        102    2       A
2  201802        103    3       B
3  201802        104    4       B

-

df1.join(df2, on='date')
       date  org_index  val dateval
101  201801        101    1       A
102  201801        102    2       A
103  201802        103    3       B
104  201802        104    4       B

È corretto. Se uniamo i due frame di dati su colonne diverse dagli indici otterremo un nuovo indice, ma se uniamo gli indici di entrambi i frame di dati otterremo un frame di dati con lo stesso indice. Quindi, al fine di ottenere lo stesso indice dopo l'unione, possiamo rendere le colonne il nostro indice (su cui vogliamo unire) per entrambi i frame di dati e quindi unire i frame di dati sull'indice appena creato.
Hasan Najeeb,

Molto perspicace. Non ho mai avuto bisogno dell'indicizzazione (di solito ho appena ripristinato l'indice) ma in alcuni casi questo potrebbe fare una grande differenza.
Irene,

4
  • Partecipa: indice predefinito (se uno stesso nome di colonna genererà un errore in modalità predefinita perché non hai definito lsuffix o rsuffix))
df_1.join(df_2)
  • Unisci: predefiniti stessi nomi di colonna (se non ha lo stesso nome di colonna, verrà generato un errore in modalità predefinita)
df_1.merge(df_2)
  • on Il parametro ha un significato diverso in entrambi i casi
df_1.merge(df_2, on='column_1')

df_1.join(df_2, on='column_1') // It will throw error
df_1.join(df_2.set_index('column_1'), on='column_1')

2

Per dirla in modo analogo a SQL "L'unione dei panda è l'unione esterna / interna e l'unione dei panda è l'unione naturale". Pertanto, quando si utilizza l'unione in Panda, si desidera specificare quale tipo di join sqlish si desidera utilizzare, mentre quando si utilizza Panda Panda, si desidera davvero avere un'etichetta di colonna corrispondente per assicurarsi che si unisca

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.