Volver a la lista

Fusión de DataFrames: `merge` y `concat`

Aprenda las diferencias y cómo usar `merge`, `concat` y `join` para combinar dos DataFrames en pandas.

Intermedio
|
10min
|
Verificado (2026-07)
mergeconcatfusión de DataFrameinner joinleft join
Progreso0/17 (0%)

Fusión de DataFrames: merge y concat

Al finalizar este tema

Podrás diferenciar claramente entre merge y concat, comprenderás los tipos de combinación inner, left, right y outer, y sabrás elegir el método de fusión adecuado en entornos profesionales.


¿Cuándo es necesaria la fusión?

En la práctica, los datos suelen estar distribuidos en varias tablas.

text
tabla usuarios:           tabla pedidos:
┌────┬──────┐           ┌─────────┬────────┬────────┐
│ id │ name │           │ order_id│ user_id│ amount │
├────┼──────┤           ├─────────┼────────┼────────┤
│  1 │ Alice│           │    101  │    1   │   5000 │
│  2 │ Bob  │           │    102  │    2   │   3000 │
│  3 │ Carol│           │    103  │    1   │   7000 │
└────┴──────┘           └─────────┴────────┴────────┘

Para calcular el "total de pedidos por usuario", es necesario combinar ambas tablas. Esto se denomina fusión.


Fusión: combinar según una clave

merge() es equivalente a la operación JOIN de SQL. Combina dos DataFrames basándose en una columna común (clave).

python
import pandas as pd
users = pd.DataFrame({
"user_id": [1, 2, 3],
"name": ["Alice", "Bob", "Carol"]
})
orders = pd.DataFrame({
"order_id": [101, 102, 103],
"user_id": [1, 2, 1],
"amount": [5000, 3000, 7000]
})
result = pd.merge(users, orders, on="user_id")
print(result)
# user_id name order_id amount
# 0 1 Alice 101 5000
# 1 1 Alice 103 7000
# 2 2 Bob 102 3000

Como Alice tiene dos pedidos, se muestra en dos filas. Carol no tiene pedidos, por lo que no aparece en el resultado; este es el comportamiento básico de un inner join.


Tipos de unión

python
users = pd.DataFrame({
"user_id": [1, 2, 3],
"name": ["Alice", "Bob", "Carol"]
})
orders = pd.DataFrame({
"order_id": [101, 102, 104],
"user_id": [1, 2, 4],
"amount": [5000, 3000, 8000]
})
# user_id=3(Carol) no tiene pedidos, user_id=4 no existe en la tabla de usuarios

Unión interna (valor predeterminado)

Solo las claves que existen en ambos conjuntos.

python
pd.merge(users, orders, on="user_id", how="inner")
# user_id name order_id amount
# 0 1 Alice 101 5000
# 1 2 Bob 102 3000

Unión izquierda

Conserva todas las filas del DataFrame izquierdo. Si no hay coincidencia en el DataFrame derecho, se inserta un valor NaN.

python
pd.merge(users, orders, on="user_id", how="left")
# user_id name order_id amount
# 0 1 Alice 101.0 5000.0
# 1 2 Bob 102.0 3000.0
# 2 3 Carol NaN NaN

Carol no tiene pedidos, pero aparece en los resultados.

Unión Derecha

Conserva todas las filas del DataFrame derecho.

python
pd.merge(users, orders, on="user_id", how="right")
# user_id name order_id amount
# 0 1 Alice 101 5000
# 1 2 Bob 102 3000
# 2 4 NaN 104 8000

El usuario con ID de usuario BP083Pnnnn no está en la tabla de usuarios, pero se incluye en los resultados.

Unión externa

Mantiene todas las filas de ambos lados.

python
pd.merge(users, orders, on="user_id", how="outer")
# user_id name order_id amount
# 0 1 Alice 101.0 5000.0
# 1 2 Bob 102.0 3000.0
# 2 3 Carol NaN NaN
# 3 4 NaN 104.0 8000.0

Cuando los nombres de las columnas clave difieren

python
users = pd.DataFrame({"id": [1, 2], "name": ["Alice", "Bob"]})
orders = pd.DataFrame({"customer_id": [1, 2], "amount": [5000, 3000]})
# uso de left_on / right_on
pd.merge(users, orders, left_on="id", right_on="customer_id")
# id name customer_id amount
# 0 1 Alice 1 5000
# 1 2 Bob 2 3000

concat: simplemente apilar

concat() concatena DataFrames vertical u horizontalmente sin necesidad de coincidencia de claves.

Vertical (axis=0, valor predeterminado)

python
jan = pd.DataFrame({"product": ["A", "B"], "sales": [100, 200]})
feb = pd.DataFrame({"product": ["A", "B"], "sales": [150, 250]})
quarterly = pd.concat([jan, feb], ignore_index=True)
# product sales
# 0 A 100
# 1 B 200
# 2 A 150
# 3 B 250

Al usar ignore_index=True, el índice se restablece a 0. Si no se usa, se repiten los índices originales (0, 1, 0, 1).

Eje horizontal (axis=1)

python
info = pd.DataFrame({"name": ["Alice", "Bob"], "age": [30, 25]})
scores = pd.DataFrame({"math": [90, 85], "english": [88, 92]})
combined = pd.concat([info, scores], axis=1)
# name age math english
# 0 Alice 30 90 88
# 1 Bob 25 85 92

Combinar vs. concatenar: ¿cuándo usar cada uno?

CombinarConcatenar
PropósitoCombinar datos mediante la correspondencia de claves comunesSimplemente apilar o concatenar
Analogía en SQLJOINUNION
Requiere claveSí (on, left_on/right_on)No
DirecciónHorizontal (agrega columnas)Vertical u horizontal
Casos de usoUsuario + pedido, producto + categoríaCombinar datos mensuales, combinar archivos divididos
text
"Conectar usuarios y pedidos" → merge (coincidencia por clave)
"Unir datos de enero y febrero" → concat (apilado simple)

Consideraciones al fusionar: duplicados e inconsistencias de claves

Expansión de filas en la fusión de muchos a muchos

python
# un user_id con múltiples pedidos, múltiples envíos
orders = pd.DataFrame({
"user_id": [1, 1, 1],
"order_id": [101, 102, 103]
})
shipments = pd.DataFrame({
"user_id": [1, 1],
"shipment_id": ["S1", "S2"]
})
result = pd.merge(orders, shipments, on="user_id")
print(len(result)) # ¡6! (3 × 2 = producto cartesiano)

Si hay varias claves idénticas en ambos lados, se generan todas las combinaciones posibles. 3 filas × 2 filas = 6 filas. En conjuntos de datos grandes, esta operación de combinación puede provocar un consumo excesivo de memoria. Se puede evitar utilizando el parámetro validate:

python
pd.merge(orders, shipments, on="user_id", validate="many_to_one")
# MergeError: Merge keys are not unique in right dataset

Patrón práctico: Combinar varios archivos

python
import os
import pandas as pd
data_dir = "monthly_reports"
all_dfs = []
for filename in sorted(os.listdir(data_dir)):
if filename.endswith(".csv"):
filepath = os.path.join(data_dir, filename)
df = pd.read_csv(filepath)
df["source_file"] = filename
all_dfs.append(df)
combined = pd.concat(all_dfs, ignore_index=True)
print(f"Total rows: {len(combined)}")

Este es el patrón para combinar archivos CSV mensuales en un solo archivo. Se puede agregar la columna source_file para realizar un seguimiento del origen de cada registro.


Resumen clave

FunciónPropósitoParámetros clave
merge()Fusión basada en claves (JOIN)on, how, left_on/right_on
concat()Concatenación (UNION)axis, ignore_index
Tipo de JOINAlcance
innerSolo las claves presentes en ambos conjuntos de datos
leftTodos los registros del conjunto de datos izquierdo, más las coincidencias del conjunto de datos derecho
rightTodos los registros del conjunto de datos derecho, más las coincidencias del conjunto de datos izquierdo
outerTodos los registros de ambos conjuntos de datos (se muestran valores NaN si no hay coincidencia)

El 80% del análisis de datos consiste en combinar la tabla correcta de la manera correcta. Comprender claramente la diferencia entre merge y concat, así como el funcionamiento de los cuatro tipos de JOIN, permite prevenir los errores más comunes en el preprocesamiento de datos: filas duplicadas, gran cantidad de valores NaN e inconsistencias en las claves.


💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...