INNER | ( LEFT | RIGHT | FULL ) OUTER ) JOIN con pandas?merge ? join ? concat ? update ? ¿Quién? ¿Qué? ¡¿Por qué?!... y más. He visto estas preguntas recurrentes sobre varias facetas de la funcionalidad de fusión de pandas. La mayor parte de la información sobre la fusión y sus diversos casos de uso hoy en día está fragmentada en docenas de publicaciones mal redactadas e inescrutables. El objetivo aquí es recopilar algunos de los puntos más importantes para la posteridad.
Esta sesión de preguntas y respuestas está destinada a ser la próxima entrega de una serie de útiles guías de usuario sobre modismos comunes de pandas (consulte esta publicación sobre pivoting y esta publicación sobre concatenación , que abordaré más adelante).
Tenga en cuenta que esta publicación no pretende ser un reemplazo de la documentación , ¡así que léala también! Algunos de los ejemplos están tomados de allí.
Para facilitar el acceso.
Esta publicación tiene como objetivo brindar a los lectores una introducción a la fusión con sabor a SQL con Pandas, cómo usarla y cuándo no usarla.
En particular, esto es lo que pasará en esta publicación:
Los conceptos básicos: tipos de uniones (IZQUIERDA, DERECHA, EXTERIOR, INTERIOR)
Lo que esta publicación (y otras publicaciones mías en este hilo) no pasará:
Nota La mayoría de los ejemplos predeterminados son operaciones INNER JOIN mientras muestran varias funciones, a menos que se especifique lo contrario.
Además, todos los DataFrames aquí se pueden copiar y replicar para que pueda jugar con ellos. Además, vea esta publicación sobre cómo leer DataFrames desde su portapapeles.
Por último, todas las representaciones visuales de las operaciones JOIN se han dibujado a mano con Dibujos de Google. Inspiración desde aquí .
merge ! np.random.seed(0) left = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': np.random.randn(4)}) right = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': np.random.randn(4)}) left key value 0 A 1.764052 1 B 0.400157 2 C 0.978738 3 D 2.240893 right key value 0 B 1.867558 1 D -0.977278 2 E 0.950088 3 F -0.151357En aras de la simplicidad, la columna clave tiene el mismo nombre (por ahora).
Un INNER JOIN está representado por

Tenga en cuenta que esto, junto con las próximas cifras, siguen esta convención:
- azul indica filas que están presentes en el resultado de la combinación
- rojo indica filas que están excluidas del resultado (es decir, eliminadas)
- el verde indica valores faltantes que se reemplazan con
NaNs en el resultado
Para realizar un INNER JOIN, llame a merge en el DataFrame izquierdo, especificando el DataFrame derecho y la clave de unión (como mínimo) como argumentos.
left.merge(right, on='key') # Or, if you want to be explicit # left.merge(right, on='key', how='inner') key value_x value_y 0 B 0.400157 1.867558 1 D 2.240893 -0.977278 Esto devuelve solo las filas de left y right que comparten una clave común (en este ejemplo, "B" y "D).
UNA UNIÓN EXTERNA IZQUIERDA , o UNIÓN IZQUIERDA está representada por

Esto se puede realizar especificando how='left' .
left.merge(right, on='key', how='left') key value_x value_y 0 A 1.764052 NaN 1 B 0.400157 1.867558 2 C 0.978738 NaN 3 D 2.240893 -0.977278 Tenga en cuenta cuidadosamente la ubicación de NaNs aquí. Si especifica how='left' , solo se usan las claves de left y los datos faltantes de la right se reemplazan por NaN.
Y de manera similar, para un RIGHT OUTER JOIN , o RIGHT JOIN que es...

... especificar how='right' :
left.merge(right, on='key', how='right') key value_x value_y 0 B 0.400157 1.867558 1 D 2.240893 -0.977278 2 E NaN 0.950088 3 F NaN -0.151357 Aquí, se utilizan las claves de right y los datos faltantes de la left se reemplazan por NaN.
Finalmente, para el FULL OUTER JOIN , dado por

especificar how='outer' .
left.merge(right, on='key', how='outer') key value_x value_y 0 A 1.764052 NaN 1 B 0.400157 1.867558 2 C 0.978738 NaN 3 D 2.240893 -0.977278 4 E NaN 0.950088 5 F NaN -0.151357Esto usa las claves de ambos marcos y se insertan NaN para las filas que faltan en ambos.
La documentación resume muy bien estas diversas fusiones:
Si necesita LEFT-Excluyendo JOIN y RIGHT-Excluyendo JOIN en dos pasos.
Para LEFT-Excluyendo JOIN, representado como

Comience realizando una UNIÓN EXTERNA IZQUIERDA y luego filtrando (¡excluyendo!) las filas que provienen solo de left ,
(left.merge(right, on='key', how='left', indicator=True) .query('_merge == "left_only"') .drop('_merge', 1)) key value_x value_y 0 A 1.764052 NaN 2 C 0.978738 NaNDonde,
left.merge(right, on='key', how='left', indicator=True ) key value_x value_y _merge 0 A 1.764052 NaN left_only 1 B 0.400157 1.867558 both 2 C 0.978738 NaN left_only 3 D 2.240893 -0.977278 bothY de manera similar, para un RIGHT-Excluyendo JOIN,

(left.merge(right, on='key', how='right', indicator=True ) .query('_merge == "right_only"') .drop('_merge', 1)) key value_x value_y 2 E NaN 0.950088 3 F NaN -0.151357Por último, si debe realizar una combinación que solo conserve las claves de la izquierda o la derecha, pero no de ambas (IOW, realizando un ANTI-JOIN ),

Puedes hacer esto de manera similar:
(left.merge(right, on='key', how='outer', indicator=True) .query('_merge != "both"') .drop('_merge', 1)) key value_x value_y 0 A 1.764052 NaN 2 C 0.978738 NaN 4 E NaN 0.950088 5 F NaN -0.151357 Si las columnas clave tienen nombres diferentes, por ejemplo, left tiene keyLeft y right tiene keyRight en lugar de key , entonces deberá especificar left_on y right_on como argumentos en lugar de on :
left2 = left.rename({'key':'keyLeft'}, axis=1) right2 = right.rename({'key':'keyRight'}, axis=1) left2 keyLeft value 0 A 1.764052 1 B 0.400157 2 C 0.978738 3 D 2.240893 right2 keyRight value 0 B 1.867558 1 D -0.977278 2 E 0.950088 3 F -0.151357 left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner') keyLeft value_x keyRight value_y 0 B 0.400157 B 1.867558 1 D 2.240893 D -0.977278 Al fusionar keyLeft desde left y keyRight desde right , si solo desea keyLeft o keyRight (pero no ambos) en la salida, puede comenzar configurando el índice como un paso preliminar.
left3 = left2.set_index('keyLeft') left3.merge(right2, left_index=True, right_on='keyRight') value_x keyRight value_y 0 0.400157 B 1.867558 1 2.240893 D -0.977278 Compare esto con la salida del comando justo antes (es decir, la salida de left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner') ), notará que falta keyLeft . Puede averiguar qué columna mantener en función del índice del cuadro que se establece como clave. Esto puede ser importante cuando, por ejemplo, se realiza alguna operación OUTER JOIN.
DataFramesPor ejemplo, considere
right3 = right.assign(newcol=np.arange(len(right))) right3 key value newcol 0 B 1.867558 0 1 D -0.977278 1 2 E 0.950088 2 3 F -0.151357 3Si debe fusionar solo "new_val" (sin ninguna de las otras columnas), por lo general, solo puede crear subconjuntos de columnas antes de fusionar:
left.merge(right3[['key', 'newcol']], on='key') key value newcol 0 B 0.400157 0 1 D 2.240893 1 Si está haciendo una UNIÓN EXTERNA IZQUIERDA, una solución de mayor rendimiento implicaría map :
# left['newcol'] = left['key'].map(right3.set_index('key')['newcol'])) left.assign(newcol=left['key'].map(right3.set_index('key')['newcol'])) key value newcol 0 A 1.764052 NaN 1 B 0.400157 0.0 2 C 0.978738 NaN 3 D 2.240893 1.0Como se mencionó, esto es similar, pero más rápido que
left.merge(right3[['key', 'newcol']], on='key', how='left') key value newcol 0 A 1.764052 NaN 1 B 0.400157 0.0 2 C 0.978738 NaN 3 D 2.240893 1.0 Para unirse a más de una columna, especifique una lista para on (o left_on y right_on , según corresponda).
left.merge(right, on=['key1', 'key2'] ...)O, en caso de que los nombres sean diferentes,
left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])merge*Fusionar un DataFrame con Series en el índice: consulte esta respuesta .
Además de merge , DataFrame.update y DataFrame.combine_first también se usan en ciertos casos para actualizar un DataFrame con otro.
pd.merge_ordered es una función útil para JOIN ordenados.
pd.merge_asof (léase: merge_asOf) es útil para uniones aproximadas .
Esta sección solo cubre los conceptos básicos y está diseñada solo para abrir el apetito. Para obtener más ejemplos y casos, consulte la documentación sobre merge , join y concat , así como los enlaces a las especificaciones de la función.
Vaya a otros temas en Pandas Merging 101 para continuar aprendiendo:
*Estás aquí.
Una vista visual complementaria de pd.concat([df0, df1], kwargs) . Tenga en cuenta que el significado de kwarg axis=0 o axis=1 no es tan intuitivo como df.mean() o df.apply(func)
Estas animaciones podrían ser mejores para explicarte visualmente. Créditos: Garrick Aden-Buie tidyexplain repo