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?
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
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()
:
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
).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)
.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 internemerge
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 pourmerge
). Si vous vous inscrivez dans l'index, vous pouvez utiliserDataFrame.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)
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
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')
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
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.
df_1.join(df_2)
df_1.merge(df_2)
on
a une signification différente dans les deux casdf_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')