Unire due frame di dati per indice


160

Ciao, ho i seguenti frame di dati:

> 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

Come unire gli indici per ottenere:

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

Chiedo perché è mia comprensione che ad merge()esempio df1.merge(df2)utilizza le colonne per fare la corrispondenza. In effetti, facendo questo ottengo:

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

È una cattiva pratica unire l'indice? È impossibile? In tal caso, come posso spostare l'indice in una nuova colonna chiamata "indice"?

Grazie


3
prova questo:df1.join(df2)
MaxU

Che cosa succede se si desidera unire l'indice di un frame di dati e una colonna del secondo frame di dati. (Il mio secondo frame di dati ha una colonna che coincide con gli indeces nel primo df.)
Mike

Risposte:


321

Usa merge, che è join interno per impostazione predefinita:

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

Oppure join, che viene lasciato unito per impostazione predefinita:

df1.join(df2)

Oppure concat, che è join esterno per impostazione predefinita:

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

Campioni :

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

2
simpatico. per gli altri che leggono questo, se non funziona, vedi se hai bisogno di .transpose()uno dei tuoi dfs per sincronizzare gli indici - quello era il mio problema
Jona,

2
Molte grazie. Bella risposta. Ma perché concatdeve mettere df tra parentesi mentre joine mergeno?
Bowen Liu,

@Bowen Liu Secondo me per possibili concatenare più DataFrames nell'elenco come dfs = [df1, df2, df3,... dfn]e poidf = pd. concat(dfs)
jezrael

@jezrael Potresti per favore controllare la mia nuova domanda su stackoverflow.com/questions/57133848/…
Msquare

29

puoi usare concat ([df1, df2, ...], axis = 1) per concatenare due o più DF allineati da indici:

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

o unisci per concatenare per campi / indici personalizzati:

# 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)

o unisciti per unirti per indice:

 df1.join(df2)

6

Per impostazione predefinita:
joinè un join sinistro in base alla
pd.mergecolonna
pd.concatè un join interno in base alla colonna è un join esterno in base alla riga

pd.concat:
accetta argomenti Iterable. Pertanto, non può accettare direttamente DataFrame (utilizzare [df,df2]) Le
dimensioni di DataFrame devono corrispondere lungo l'asse

Joine pd.merge:
può accettare argomenti DataFrame


5

Un bug stupido che mi ha procurato: i join falliscono perché l'indice dtypesdifferiva. Ciò non era ovvio poiché entrambe le tabelle erano tabelle pivot della stessa tabella originale. Successivamente reset_index, gli indici sembravano identici in Jupyter. È venuto alla luce solo quando si salva in Excel ...

Risolto con: df1[['key']] = df1[['key']].apply(pd.to_numeric)

Spero che questo salvi qualcuno all'ora!


4

Se vuoi unire due frame di dati in Panda puoi semplicemente usare gli attributi disponibili come mergeo concatenate. Ad esempio, se ho due frame di dati df1e df2posso unirli a loro:

newdataframe=merge(df1,df2,left_index=True,right_index=True)
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.