Fusionner deux dataframes par index

160

Salut, j'ai les dataframes suivants:

> df1
  id begin conditional confidence discoveryTechnique  
0 278    56       false        0.0                  1   
1 421    18       false        0.0                  1 

> df2
   concept 
0  A  
1  B

Comment fusionner les indices pour obtenir:

  id begin conditional confidence discoveryTechnique   concept 
0 278    56       false        0.0                  1  A 
1 421    18       false        0.0                  1  B

Je demande parce que je crois comprendre que merge()c'est à dire df1.merge(df2)utilise des colonnes pour faire la correspondance. En fait, en faisant cela, j'obtiens:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pandas/core/frame.py", line 4618, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 58, in merge
    copy=copy, indicator=indicator)
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 491, in __init__
    self._validate_specification()
  File "/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.py", line 812, in _validate_specification
    raise MergeError('No common columns to perform merge on')
pandas.tools.merge.MergeError: No common columns to perform merge on

Est-ce une mauvaise pratique de fusionner sur l'index? Est-ce impossible? Si tel est le cas, comment puis-je déplacer l'index dans une nouvelle colonne appelée «index»?

Merci

brucezepplin
la source
3
essayez ceci:df1.join(df2)
MaxU
Que faire si vous souhaitez joindre par l'index d'une dataframe et une colonne de la deuxième dataframe. (Ma deuxième dataframe a une colonne qui correspond aux indéces du premier df.)
mikey

Réponses:

321

Utilisez merge, qui est une jointure interne par défaut:

pd.merge(df1, df2, left_index=True, right_index=True)

Ou join, qui reste jointe par défaut:

df1.join(df2)

Ou concat, qui est une jointure externe par défaut:

pd.concat([df1, df2], axis=1)

Échantillons :

df1 = pd.DataFrame({'a':range(6),
                    'b':[5,3,6,9,2,4]}, index=list('abcdef'))

print (df1)
   a  b
a  0  5
b  1  3
c  2  6
d  3  9
e  4  2
f  5  4

df2 = pd.DataFrame({'c':range(4),
                    'd':[10,20,30, 40]}, index=list('abhi'))

print (df2)
   c   d
a  0  10
b  1  20
h  2  30
i  3  40

#default inner join
df3 = pd.merge(df1, df2, left_index=True, right_index=True)
print (df3)
   a  b  c   d
a  0  5  0  10
b  1  3  1  20

#default left join
df4 = df1.join(df2)
print (df4)
   a  b    c     d
a  0  5  0.0  10.0
b  1  3  1.0  20.0
c  2  6  NaN   NaN
d  3  9  NaN   NaN
e  4  2  NaN   NaN
f  5  4  NaN   NaN

#default outer join
df5 = pd.concat([df1, df2], axis=1)
print (df5)
     a    b    c     d
a  0.0  5.0  0.0  10.0
b  1.0  3.0  1.0  20.0
c  2.0  6.0  NaN   NaN
d  3.0  9.0  NaN   NaN
e  4.0  2.0  NaN   NaN
f  5.0  4.0  NaN   NaN
h  NaN  NaN  2.0  30.0
i  NaN  NaN  3.0  40.0
jezrael
la source
2
agréable. pour les autres lisant ceci, si cela ne fonctionne pas, voyez si vous avez besoin d' .transpose()un de vos dfs pour synchroniser les index - c'était mon problème
Jona
2
Merci beaucoup. Très bonne réponse. Mais pourquoi faut concat-il mettre df entre parenthèses joinet mergenon?
Bowen Liu
@Bowen Liu À mon avis, pour une concatection possible de plusieurs DataFrames dans une liste comme dfs = [df1, df2, df3,... dfn]et puisdf = pd. concat(dfs)
jezrael
@jezrael Pourriez-vous s'il vous plaît vérifier ma nouvelle question à stackoverflow.com/questions/57133848/…
Msquare
29

vous pouvez utiliser concat ([df1, df2, ...], axis = 1) afin de concaténer deux ou plusieurs DF alignés par des index:

pd.concat([df1, df2, df3, ...], axis=1)

ou fusionner pour concaténer par champs / index personnalisés:

# join by _common_ columns: `col1`, `col3`
pd.merge(df1, df2, on=['col1','col3'])

# join by: `df1.col1 == df2.index`
pd.merge(df1, df2, left_on='col1' right_index=True)

ou rejoindre pour rejoindre par index:

 df1.join(df2)
MaxU
la source
6

Par défaut:
joinest une jointure gauche
pd.mergepar colonne
pd.concatest une jointure interne par colonne est une jointure externe par ligne

pd.concat:
prend des arguments Iterable. Ainsi, il ne peut pas prendre des DataFrames directement (utiliser [df,df2]) Les
dimensions de DataFrame doivent correspondre le long de l'axe

Joinet pd.merge:
peut prendre des arguments DataFrame

vicpal
la source
5

Un bogue idiot qui m'a attrapé: les jointures ont échoué parce que l'index était dtypesdifférent. Ce n'était pas évident car les deux tableaux étaient des tableaux croisés dynamiques du même tableau d'origine. Après reset_index, les indices semblaient identiques dans Jupyter. Cela n'est apparu que lors de l'enregistrement dans Excel ...

Fixé avec: df1[['key']] = df1[['key']].apply(pd.to_numeric)

Espérons que cela sauve quelqu'un une heure!

Stephen Morrell
la source
4

Si vous voulez joindre deux dataframes dans pandas, vous pouvez simplement utiliser les attributs disponibles comme mergeou concatenate. Par exemple, si j'ai deux dataframes df1et que df2je peux les rejoindre en:

newdataframe=merge(df1,df2,left_index=True,right_index=True)
vignesh babu
la source