La idea
Un merge no pega dos tablas una al lado de la otra. Mira una columna clave y, para cada fila de la izquierda, busca las filas de la derecha con el mismo valor de clave. Cada coincidencia se convierte en una fila del resultado, con las columnas de ambos lados rellenas.
Esa frase lo predice todo. El resultado tiene una fila por coincidencia, así que su longitud
depende de cuántas veces se repite cada clave. Una clave que aparece una vez en cada lado da una
fila. Una clave que aparece tres veces a la derecha da tres filas, con los valores de la izquierda
copiados tres veces. Una clave sin pareja da cero filas o una fila de NaN, según how=.
Figura 1
customers.merge(orders, on='customer_id', how='left', indicator=True)
| customer_id | first_name | city |
|---|---|---|
| 69 | Gary | Chicago |
| 70 | Sandra | Tucson |
| 151 | Henry | Orlando |
| order_id | customer_id | channel |
|---|---|---|
| 1231 | 69 | web |
| 3071 | 70 | web |
| 4230 | 69 | web |
| 11163 | 70 | app |
| first_name | order_id | channel | _merge |
|---|---|---|---|
| Gary | 1231 | web | both |
| Gary | 4230 | web | both |
| Sandra | 3071 | web | both |
| Sandra | 11163 | app | both |
| Henry | NULL | NULL | left_only |
- Dos DataFrames que comparten
customer_id. Encustomerses único, una fila por persona. Enordersse repite, una vez por pedido. - pandas toma cada fila de la izquierda y busca filas de la derecha con la misma clave. Gary (69) coincide con los pedidos 1231 y 4230.
- Una fila de resultado por coincidencia. El nombre de Gary se copia en las dos filas, y
_mergediceboth: la clave se encontró en ambos lados. - Sandra (70) también tiene dos pedidos, así que también aparece dos veces.
- Henry (151) no tiene pedidos.
how='left'lo conserva igualmente, conNaNdondeordershabría puesto datos.indicator=Truemarca la fila comoleft_only, y así puedes filtrar por eso.
Por qué existe
Harbor & Pine guarda cada dato una sola vez. La ciudad de un cliente está en customers, el canal de
un pedido en orders, el precio de una lámpara en products. Eso mantiene los datos correctos,
pero casi toda pregunta cruza tablas: los ingresos por categoría necesitan order_items y
products; los clientes que nunca compraron necesitan customers y orders.
Sin merge copiarías valores a mano, o escribirías un bucle y buscarías cada fila. Un merge hace la
búsqueda de todas las filas a la vez y te deja un solo DataFrame para agrupar, filtrar o graficar.
También mantiene honestas las fuentes. Cuando Marketing dice que un informe está mal, puedes rastrear el número: qué tablas entraron, con qué clave y cuántas filas salieron. Un merge es una declaración corta y legible de cómo se relacionan dos datos, y eso vale más que la búsqueda en sí. El precio es que la relación tiene que ser la correcta, y la siguiente sección trata de comprobarlo.
Cómo funciona por dentro
Paso a paso
- Elige la clave.
on='customer_id'cuando ambas tablas usan el mismo nombre,left_on=yright_on=cuando no. - Empareja. Cada fila izquierda se une con cada fila derecha que tenga la misma clave.
- Gestiona los fallos.
how='inner'(el valor por defecto) descarta las filas sin pareja de ambos lados.how='left'conserva todas las de la izquierda,how='right'todas las de la derecha,how='outer'las de los dos lados. - Resuelve choques de nombres. Si las dos tablas tienen una columna
unit_price, pandas conserva ambas y añade_xe_y. Pasasuffixes=('_item', '_product')para elegir mejores nombres.
indicator=True añade una columna _merge que indica de dónde viene cada fila: both, left_only
o right_only. Filtra por left_only después de un merge left y tendrás los clientes que nunca
compraron. Un simple NaN también podría significar "tuvo pareja, pero el valor falta", así que el
indicador es la prueba segura.
El grano decide el número de filas
El grano de una tabla es lo que representa una fila. orders: un pedido. order_items: una
línea de pedido. customers: un cliente. Antes de cualquier merge, di en voz alta el grano de ambos
lados. Clientes a pedidos es uno a muchos. Pedidos a líneas es uno a muchos. Líneas a productos es
muchos a uno, porque cada línea apunta a un solo producto: un merge muchos a uno nunca cambia el
número de filas. Un merge muchos a muchos, donde la clave se repite en ambos lados, multiplica: 3
coincidencias a la izquierda por 4 a la derecha son 12 filas.
Fan-out
Cuando el lado derecho tiene muchas filas por clave, las columnas de la tabla izquierda se repiten. Contar o sumar columnas del lado derecho sigue siendo correcto. Sumar una columna que pertenece a la tabla izquierda no lo es.
Figura 2
orders.merge(order_items, on='order_id'): una tarifa, tres líneas
| order_id | channel | shipping_fee |
|---|---|---|
| 1049 | web | 4.99 |
| order_item_id | order_id | quantity |
|---|---|---|
| 139 | 1049 | 2 |
| 140 | 1049 | 2 |
| 141 | 1049 | 3 |
| order_id | order_item_id | shipping_fee |
|---|---|---|
| 1049 | 139 | 4.99 |
| 1049 | 140 | 4.99 |
| 1049 | 141 | 4.99 |
- El pedido 1049 pagó el envío una vez: $4.99. La tarifa vive en el pedido, porque el envío se cobra por pedido.
- El mismo pedido tiene tres filas en
order_items. Un merge pororder_idencuentra tres coincidencias. - Tres coincidencias, tres filas. La tarifa se copia en cada una. Cada columna de la tabla izquierda se repite una vez por coincidencia.
- Haz
.sum()sobreshipping_feeya unido y este pedido cuenta $14.97. En los 12,000 pedidos, los $32,016.06 reales pasan a ser $58,782.63.
Imagina a una colega de finanzas comparando tu total con el del proveedor de pagos: el tuyo es un 80%
más alto y nadie sabe por qué. Nada da error y el número parece plausible, por eso este fallo llega
hasta los informes. Hay dos remedios. Agrega la columna por pedido en orders antes de unir, o
reduce primero la tabla derecha a una fila por clave con groupby. Y deja que pandas te vigile:
validate='one_to_many' falla con un error si la clave izquierda se repite, validate='many_to_one'
si se repite la derecha, y 'one_to_one' si se repite cualquiera.
Figura 3
El hábito que mantiene honesto a un merge
- Conoce el grano ¿una fila por qué?
-
len(orders)12,000 -
orders.merge(order_items, on='order_id', validate='one_to_many') -
len(merged)30,338 - Agrega solo columnas de la tabla más fina
- Primero decide qué significa una fila en cada tabla.
orderses una fila por pedido,order_itemsuna fila por línea de pedido. - Cuenta las filas antes.
validate='one_to_many'hace que pandas lance un error si la clave izquierda no es única, así que una suposición equivocada detiene el script. - El conteo después es 30,338, el número de líneas de pedido. Coincide con un merge uno a muchos. Si hubieran sido 12,000 o 40,000, te detendrías a mirar.
- Solo ahora suma. Los ingresos salen de las líneas. Una columna por pedido como
shipping_feese suma enorders, antes del merge.
Las claves deben ser el mismo tipo de valor
Un merge empareja valores iguales, así que '101' como texto no coincidirá con 101 como número, y
' Texas' no coincidirá con 'Texas'. Si un merge left rellena todo con NaN, revisa primero
df.dtypes en las columnas clave y luego limpia el texto. Lo mismo vale para las claves NaN:
web_sessions.customer_id está vacío para los visitantes anónimos, y pandas emparejará esas claves
vacías entre sí si el otro lado también las tiene. Elimínalas antes.
Errores comunes
"Un merge left devuelve tantas filas como la tabla izquierda"
Devuelve al menos tantas, siempre que las claves sean únicas a la derecha. Un merge left de
customers con orders tiene 12,247 filas, no 2,018. La tabla izquierda decide qué filas se
conservan, no cuántas veces aparecen. Compara len() antes y después de cada merge.
"Si el merge se ejecutó sin error, los números son correctos"
pandas no tiene forma de saber que querías una fila por pedido. El fan-out, las claves equivocadas
y los tipos distintos se ejecutan sin avisar. La comprobación es tuya: número de filas frente al
grano, indicator=True para las filas sin pareja y validate= para dejar tu suposición escrita en
el código.
"NaN después de un merge significa que faltan datos"
Después de un merge left, un NaN en las columnas de la derecha casi siempre significa "no hay fila
que coincida". El order_id ausente de Henry no es un hueco en la base de datos, es un cliente sin
pedidos. Decide cuál de los dos es antes de rellenarlo: un cliente sin pedidos tiene ingresos cero,
una respuesta real, mientras que un producto sin costo es un problema de datos.
Ponte a prueba
Una pregunta. Al responderla, la lección queda marcada en el mapa; nunca bloquea un nivel.
No del todo. Un merge left conserva todas las filas de la izquierda, pero un cliente con cinco pedidos produce cinco filas. El conteo solo iguala al de clientes si nadie tiene más de un pedido.Prueba otra respuesta.
Correcto. Un cliente con n pedidos da n filas; uno sin pedidos da una sola fila de NaN. Los 247 suman 247 filas, y los clientes con varios pedidos suman muchas más.
No del todo. Eso es how='inner'. Un merge left conserva las filas izquierdas sin pareja y rellena las columnas de la derecha con NaN.Prueba otra respuesta.
No del todo. Aquí los pedidos son la tabla derecha. Un merge left conserva a todos los clientes, incluidos los 247 sin pedidos, así que el conteo es 12,000 + 247 = 12,247.Prueba otra respuesta.
Lección hecha: ya está marcada en el mapa.