certmundo.
es‑mx

6 min de lectura

¿Cómo combinar múltiples fuentes de datos con merge y concat?

merge() y concat() son las dos funciones principales de pandas para combinar DataFrames provenientes de distintas fuentes.

En análisis de datos reales, la información rara vez viene en una sola tabla. Un sistema de ventas de Liverpool puede guardar los tickets en un archivo y el catálogo de productos en otro. Para analizarlos juntos, necesitas unirlos.


merge(): unión tipo SQL JOIN

merge() une dos DataFrames usando una o más columnas como llave común.

Funciona exactamente igual que un JOIN en SQL. Buscas filas donde el valor de la llave coincide en ambas tablas.

Sintaxis básica

resultado = pd.merge(df_izquierdo, df_derecho, on="columna_llave", how="tipo")
  • on: nombre de la columna llave (debe existir en ambos DataFrames).
  • how: tipo de unión. Los valores posibles son "inner", "left", "right" y "outer".

Tipos de unión con how

Tipo Qué devuelve
inner Solo filas con llave en ambas tablas
left Todas las filas del DataFrame izquierdo
right Todas las filas del DataFrame derecho
outer Todas las filas de ambas tablas

El tipo más común en análisis de datos es left. Conservas todos tus registros de ventas aunque el producto no esté en el catálogo.


Ejemplo 1: cruzar ventas con catálogo de productos

Supón que tienes dos tablas de un sistema de FEMSA.

import pandas as pd

# Tabla de ventas
ventas = pd.DataFrame({
    "id_producto": [101, 102, 103, 104],
    "cantidad": [5, 3, 8, 2],
    "precio_unitario": [18500, 9500, 4200, 31000]
})

# Catálogo de productos
catalogo = pd.DataFrame({
    "id_producto": [101, 102, 103],
    "nombre_producto": ["Refresco 600ml", "Agua 1.5L", "Jugo 1L"],
    "categoria": ["Bebidas", "Bebidas", "Jugos"]
})

# Unión left: conserva todas las ventas
resultado = pd.merge(ventas, catalogo, on="id_producto", how="left")
print(resultado)

Resultado:

   id_producto  cantidad  precio_unitario  nombre_producto categoria
0          101         5            18500   Refresco 600ml   Bebidas
1          102         3             9500        Agua 1.5L   Bebidas
2          103         8             4200         Jugo 1L     Jugos
3          104         2            31000              NaN       NaN

El producto 104 no existe en el catálogo. Con how="left" se conserva, pero con valores NaN en las columnas del catálogo. Con how="inner" esa fila desaparecería.


Ejemplo 2: merge con llaves de nombre diferente

A veces la misma columna tiene nombres distintos en cada tabla. Usa left_on y right_on.

# Tabla de empleados de Bimbo
empleados = pd.DataFrame({
    "num_empleado": [1001, 1002, 1003],
    "nombre": ["Ana Torres", "Luis Pérez", "María García"],
    "salario": [18500, 22000, 15800]
})

# Tabla de evaluaciones
evaluaciones = pd.DataFrame({
    "id_emp": [1001, 1002, 1004],
    "calificacion": [9.5, 8.0, 7.2]
})

resultado = pd.merge(
    empleados,
    evaluaciones,
    left_on="num_empleado",
    right_on="id_emp",
    how="left"
)
print(resultado[["nombre", "salario", "calificacion"]])

Resultado:

       nombre  salario  calificacion
0  Ana Torres    18500           9.5
1  Luis Pérez    22000           8.0
2 María García   15800           NaN

María García no tiene evaluación registrada. Con how="left" se mantiene en el resultado con NaN.


Ejemplo 3: merge con múltiples llaves

Puedes unir por más de una columna al mismo tiempo. Esto es útil cuando la combinación de dos columnas identifica una fila de forma única.

# Ventas por tienda y mes en Liverpool
ventas_mes = pd.DataFrame({
    "tienda": ["CDMX", "CDMX", "MTY"],
    "mes": [1, 2, 1],
    "total_ventas": [850000, 920000, 710000]
})

# Metas por tienda y mes
metas = pd.DataFrame({
    "tienda": ["CDMX", "CDMX", "MTY"],
    "mes": [1, 2, 1],
    "meta": [800000, 900000, 750000]
})

resultado = pd.merge(ventas_mes, metas, on=["tienda", "mes"], how="inner")
resultado["cumplimiento"] = resultado["total_ventas"] / resultado["meta"]
print(resultado)

Resultado:

  tienda  mes  total_ventas     meta  cumplimiento
0   CDMX    1        850000   800000      1.062500
1   CDMX    2        920000   900000      1.022222
2    MTY    1        710000   750000      0.946667

La tienda de Monterrey no alcanzó su meta en enero.


concat(): apilar DataFrames

concat() apila DataFrames uno encima del otro (por filas) o uno al lado del otro (por columnas).

Úsalo cuando tienes la misma estructura de datos dividida en varios archivos. Por ejemplo, las ventas de Mercado Libre de enero, febrero y marzo en tres archivos separados.

Sintaxis básica

resultado = pd.concat([df1, df2, df3], axis=0, ignore_index=True)
  • axis=0: apila por filas (valor por defecto).
  • axis=1: apila por columnas.
  • ignore_index=True: reinicia el índice del DataFrame resultante.

Ejemplo 4: unir reportes mensuales de Mercado Libre

# Ventas de tres meses
enero = pd.DataFrame({
    "producto": ["Laptop", "Celular"],
    "ventas": [45000, 32000],
    "mes": ["Enero", "Enero"]
})

febrero = pd.DataFrame({
    "producto": ["Laptop", "Celular"],
    "ventas": [51000, 28000],
    "mes": ["Febrero", "Febrero"]
})

marzo = pd.DataFrame({
    "producto": ["Laptop", "Celular"],
    "ventas": [47000, 35000],
    "mes": ["Marzo", "Marzo"]
})

trimestre = pd.concat([enero, febrero, marzo], ignore_index=True)
print(trimestre)

Resultado:

  producto  ventas      mes
0   Laptop   45000    Enero
1  Celular   32000    Enero
2   Laptop   51000  Febrero
3  Celular   28000  Febrero
4   Laptop   47000    Marzo
5  Celular   35000    Marzo

Ahora puedes hacer un groupby para calcular el total trimestral por producto.


Diferencia clave entre merge y concat

Función Cuándo usarla
merge() Las tablas tienen columnas distintas y se relacionan por una llave
concat() Las tablas tienen la misma estructura y quieres apilarlas

Una regla simple: si piensas en "unir columnas nuevas", usa merge(). Si piensas en "agregar más filas", usa concat().


Errores comunes

Error 1: duplicar filas sin darse cuenta. Si la columna llave tiene valores repetidos en ambas tablas, merge() crea todas las combinaciones posibles. El resultado puede tener más filas de las esperadas. Verifica con df["llave"].value_counts() antes de hacer el merge.

Error 2: olvidar ignore_index=True en concat(). Sin este parámetro, los índices originales se conservan y pueden repetirse. Esto causa errores al acceder a filas por índice. Siempre usa ignore_index=True cuando apiles tablas de distintas fuentes.

Error 3: columnas con nombres distintos en concat(). Si dos DataFrames tienen columnas con nombres ligeramente diferentes (por ejemplo, "Ventas" y "ventas"), concat() las tratará como columnas distintas y llenará con NaN. Verifica que los nombres de columna sean idénticos antes de concatenar.

Error 4: usar how="inner" cuando no debes. Con inner, pierdes todas las filas que no tienen pareja en la otra tabla. En análisis de ventas, esto puede hacerte pensar que tienes menos registros de los que realmente existen. Cuando tengas dudas, empieza con how="left" y revisa los NaN resultantes.


Resumen de parámetros útiles

Parámetro Función Ejemplo
on Llave común en ambas tablas on="id_producto"
left_on / right_on Llaves con nombres distintos left_on="num", right_on="id"
how Tipo de unión how="left"
suffixes Renombra columnas duplicadas suffixes=("_ventas", "_cat")
ignore_index Reinicia índice en concat ignore_index=True
axis Dirección del apilado axis=0 (filas)

Puntos clave

  • Usa merge() cuando dos tablas comparten una columna llave y necesitas cruzar su información, igual que un JOIN en SQL.
  • El parámetro how="left" conserva todos los registros de la tabla izquierda, aunque no tengan pareja en la tabla derecha.
  • Usa concat() para apilar DataFrames que tienen la misma estructura, como reportes mensuales o archivos por región.
  • Siempre usa ignore_index=True al concatenar para evitar índices duplicados.
  • Antes de hacer un merge, verifica que la columna llave no tenga duplicados inesperados con value_counts().

Puntos clave

  • Usa `merge()` para cruzar dos DataFrames por una columna llave común, igual que un JOIN en SQL. Es ideal para unir ventas con catálogos de productos.
  • El parámetro `how` controla qué filas se conservan: `left` mantiene todos los registros de la tabla izquierda aunque no tengan pareja en la derecha.
  • Cuando la columna llave tiene nombres distintos en cada tabla, usa `left_on` y `right_on` en lugar de `on`.
  • Usa `concat()` para apilar DataFrames con la misma estructura, como reportes mensuales de Mercado Libre. Siempre incluye `ignore_index=True`.
  • Antes de hacer un merge, verifica duplicados en la columna llave con `value_counts()` para evitar que el resultado tenga más filas de las esperadas.

Comparte esta lección: