Combinar dos marcos de datos por índice

161

Hola, tengo los siguientes marcos de datos:

> 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

¿Cómo me fusiono en los índices para obtener:

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

Pregunto porque, según tengo entendido, merge()es decir, df1.merge(df2)utiliza columnas para hacer la correspondencia. De hecho, al hacer esto obtengo:

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

¿Es una mala práctica fusionarse en el índice? ¿Es imposible? Si es así, ¿cómo puedo cambiar el índice a una nueva columna llamada "índice"?

Gracias

brucezepplin
fuente
3
intente esto:df1.join(df2)
MaxU
¿Qué sucede si desea unirse por el índice de un marco de datos y una columna del segundo marco de datos? (Mi segundo marco de datos tiene una columna que coincide con las indeces en el primer df.)
mikey

Respuestas:

322

Uso merge, que es la unión interna de forma predeterminada:

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

O join, que se deja unir por defecto:

df1.join(df2)

O concat, que es la unión externa de forma predeterminada:

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

Muestras :

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
fuente
2
bonito. para otros que lean esto, si no funciona, vea si necesita .transpose()uno de sus dfs para sincronizar los índices, ese fue mi problema
Jona
2
Muchas gracias. Gran respuesta. Pero, ¿por qué concattiene que poner df entre paréntesis joiny mergeno?
Bowen Liu
@Bowen Liu En mi opinión para posibles concat múltiples DataFrames en la lista como dfs = [df1, df2, df3,... dfn]y luegodf = pd. concat(dfs)
jezrael
@jezrael ¿Podrías consultar mi nueva pregunta en stackoverflow.com/questions/57133848/…
Msquare
29

puede usar concat ([df1, df2, ...], axis = 1) para concatenar dos o más DF alineados por índices:

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

o fusionar para concatenar por campos / índices personalizados:

# 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 unirse para unirse por índice:

 df1.join(df2)
MaxU
fuente
6

Por defecto:
joines una combinación izquierda en
pd.mergeforma de columna
pd.concates una combinación interna en forma de columna es una combinación externa en forma de fila

pd.concat:
toma argumentos Iterable. Por lo tanto, no puede tomar DataFrames directamente (usar [df,df2]) Las
dimensiones de DataFrame deben coincidir a lo largo del eje

Joiny pd.merge:
puede tomar argumentos de DataFrame

vicpal
fuente
5

Un error tonto que me atrapó: las uniones fallaron porque el índice era dtypesdiferente. Esto no era obvio ya que ambas tablas eran tablas dinámicas de la misma tabla original. Después reset_index, los índices se veían idénticos en Jupyter. Solo salió a la luz al guardar en Excel ...

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

¡Ojalá esto le ahorre a alguien una hora!

Stephen Morrell
fuente
4

Si desea unir dos marcos de datos en pandas, simplemente puede usar los atributos disponibles como mergeo concatenate. Por ejemplo, si tengo dos marcos de datos df1y df2puedo unirlos mediante:

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