web-dev-qa-db-fra.com

Quelle est la difference entre join et fusion in Pandas?

Supposons que j'ai deux DataFrames comme ceci:

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

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

Je veux les fusionner, alors j'essaie quelque chose comme ça:

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

Et je suis content

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

Mais j'essaie d'utiliser la méthode de jointure, qui m'a semblé très similaire.

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

Et je reçois ceci:

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

Qu'est-ce que je rate?

145
munk

J'utilise toujours join sur les index:

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 même fonctionnalité peut être obtenue en utilisant merge sur les colonnes comme suit:

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
67
Paul H

pandas.merge() est la fonction sous-jacente utilisée pour tous les comportements de fusion/jointure.

Les DataFrames fournissent les méthodes pandas.DataFrame.merge() et pandas.DataFrame.join() comme un moyen pratique d'accéder aux fonctionnalités de pandas.merge(). Par exemple, df1.merge(right=df2, ...) est équivalent à pandas.merge(left=df1, right=df2, ...).

Voici les principales différences entre df.join() et df.merge():

  1. recherche sur la table de droite: df1.join(df2) se joint toujours via l'index de df2, mais df1.merge(df2) peut être associé à une ou plusieurs colonnes de df2 (valeur par défaut) ou à l'index de df2 (avec right_index=True).
  2. recherche sur le tableau de gauche: par défaut, df1.join(df2) utilise l'index de df1 et df1.merge(df2) utilise la ou les colonnes de df1. Cela peut être annulé en spécifiant df1.join(df2, on=key_or_keys) ou df1.merge(df2, left_index=True).
  3. gauche vs jointure interne: df1.join(df2) effectue une jointure gauche par défaut (conserve toutes les lignes de df1), mais df.merge effectue une jointure interne par défaut (renvoie uniquement les lignes correspondantes de df1 et df2).

Ainsi, l'approche générique consiste à utiliser pandas.merge(df1, df2) ou df1.merge(df2). Toutefois, dans un certain nombre de situations courantes (conservation de toutes les lignes de df1 et jonction à un index dans df2), vous pouvez enregistrer des opérations de frappe en utilisant df1.join(df2) à la place.

Certaines notes sur ces problèmes sont tirées de la documentation de http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging :

merge est une fonction de l'espace de noms pandas. Elle est également disponible en tant que méthode d'instance DataFrame, le DataFrame appelant étant implicitement considéré comme l'objet de gauche dans la jointure.

La méthode associée DataFrame.join utilise _ en interne merge pour les jointures index-sur-index et index-sur-colonne, mais les jointures sur les index par défaut plutôt que d'essayer de joindre des colonnes communes ( comportement par défaut pour merge). Si vous vous inscrivez dans l'index, vous pouvez utiliser DataFrame.join pour vous épargner une frappe.

...

Ces deux appels de fonction sont complètement équivalents:

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

Je crois que join() n'est qu'une méthode pratique. Essayez plutôt df1.merge(df2), ce qui vous permet de spécifier left_on et 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
Noah

http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra

pandas fournit une fonction unique, fusion, en tant que point d’entrée pour toutes les opérations de jointure de base de données standard entre objets DataFrame:

fusion (gauche, droite, comment = 'inner', on = None, left_on = None, right_on = None, left_index = False, right_index = False, sort = True, suffixes = ('_ x', '_y'), copy = Vrai, indicateur = Faux)

Et :

DataFrame.join est une méthode pratique pour combiner les colonnes de deux DataFrames potentiellement différemment indexées en un seul résultat DataFrame. Voici un exemple très basique: L'alignement des données se trouve ici sur les index (étiquettes de lignes). Ce même comportement peut être obtenu en utilisant la fusion et des arguments supplémentaires lui ordonnant d'utiliser les index: result = pd.merge (left, right, left_index = True, right_index = True, how = 'outer')

7
Romain Jouin

Une des différences est que merge crée un nouvel index et join conserve l'index de gauche. Cela peut avoir une grande conséquence sur vos transformations ultérieures si vous supposez à tort que votre index n'est pas modifié avec merge.

Par exemple:

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

Pour le dire de manière analogue à SQL "La fusion de pandas est une jointure externe/interne et la jointure Pandas est une jointure naturelle". Par conséquent, lorsque vous utilisez la fusion dans les pandas, vous souhaitez spécifier le type de jointure SQL que vous souhaitez utiliser, tandis que lorsque vous utilisez pandas join, vous souhaitez vraiment avoir un libellé de colonne correspondant pour garantir sa jointure.

1
Kaustubh J
  • Join: Default Index (Si le même nom de colonne, il générera une erreur en mode par défaut car vous n’avez pas défini lsuffix ni rsuffix))
df_1.join(df_2)
  • Fusionner: Noms de colonne identiques par défaut (si aucun nom de colonne n'est identique, une erreur sera générée en mode par défaut)
df_1.merge(df_2)
  • Le paramètre on a une signification différente dans les deux cas
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')
1
Harsh