Python · Capítulo 7 · Lección de conceptos · 7 min de lectura

Qué le hace un merge a tu número de filas

Un merge empareja filas por clave y crea una fila de resultado por cada coincidencia. Si conoces el grano de cada tabla, puedes predecir el número de filas antes de ejecutarlo y detectar el merge que duplica un total sin avisar.

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)

customers
customer_idfirst_namecity
69GaryChicago
70SandraTucson
151HenryOrlando
orders
order_idcustomer_idchannel
123169web
307170web
423069web
1116370app
Resultado
first_nameorder_idchannel_merge
Gary1231webboth
Gary4230webboth
Sandra3071webboth
Sandra11163appboth
HenryNULLNULLleft_only

Paso 1 de 5 Dos DataFrames que comparten customer_id. En customers es único, una fila por persona. En orders se repite, una vez por pedido.

  1. Dos DataFrames que comparten customer_id. En customers es único, una fila por persona. En orders se repite, una vez por pedido.
  2. 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.
  3. Una fila de resultado por coincidencia. El nombre de Gary se copia en las dos filas, y _merge dice both: la clave se encontró en ambos lados.
  4. Sandra (70) también tiene dos pedidos, así que también aparece dos veces.
  5. Henry (151) no tiene pedidos. how='left' lo conserva igualmente, con NaN donde orders habría puesto datos. indicator=True marca la fila como left_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

  1. Elige la clave. on='customer_id' cuando ambas tablas usan el mismo nombre, left_on= y right_on= cuando no.
  2. Empareja. Cada fila izquierda se une con cada fila derecha que tenga la misma clave.
  3. 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.
  4. Resuelve choques de nombres. Si las dos tablas tienen una columna unit_price, pandas conserva ambas y añade _x e _y. Pasa suffixes=('_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

orders
order_idchannelshipping_fee
1049web4.99
order_items
order_item_idorder_idquantity
13910492
14010492
14110493
Unido
order_idorder_item_idshipping_fee
10491394.99
10491404.99
10491414.99

Paso 1 de 4 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.

  1. 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.
  2. El mismo pedido tiene tres filas en order_items. Un merge por order_id encuentra tres coincidencias.
  3. Tres coincidencias, tres filas. La tarifa se copia en cada una. Cada columna de la tabla izquierda se repite una vez por coincidencia.
  4. Haz .sum() sobre shipping_fee ya 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

  1. Conoce el grano ¿una fila por qué?
  2. len(orders) 12,000
  3. orders.merge(order_items, on='order_id', validate='one_to_many')
  4. len(merged) 30,338
  5. Agrega solo columnas de la tabla más fina

Paso 1 de 4 Primero decide qué significa una fila en cada tabla. orders es una fila por pedido, order_items una fila por línea de pedido.

  1. Primero decide qué significa una fila en cada tabla. orders es una fila por pedido, order_items una fila por línea de pedido.
  2. 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.
  3. 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.
  4. Solo ahora suma. Los ingresos salen de las líneas. Una columna por pedido como shipping_fee se suma en orders, 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.

customers tiene 2,018 filas y 247 de esos clientes nunca han comprado. ¿Qué puedes decir de customers.merge(orders, on='customer_id', how='left')?

Elige qué puede ejecutarse en este sitio. Puedes cambiarlo cuando quieras desde "Configurar cookies", al pie de cada página.