¿Cómo combinar DataFrames con merge() en pandas?
Respuesta corta: merge() une dos DataFrames por una o varias columnas en común, igual que un JOIN de SQL. Indicas la columna con on y el tipo de unión con how: "inner" (por defecto), "left", "right", "outer" o "cross".
import pandas as pd
clientes = pd.DataFrame({"id": [1, 2, 3], "nombre": ["Ana", "Luis", "Marta"]})
pedidos = pd.DataFrame({"id": [1, 1, 3, 4], "total": [50, 20, 80, 35]})
print(clientes.merge(pedidos, on="id")) id nombre total
0 1 Ana 50
1 1 Ana 20
2 3 Marta 80Ana aparece dos veces porque tiene dos pedidos. Luis no sale porque no tiene pedidos, y el pedido del cliente 4 tampoco, porque ese cliente no existe. pd.merge(clientes, pedidos, on="id") hace exactamente lo mismo.
El parámetro how decide qué filas se quedan cuando una clave solo existe en una de las dos tablas.
Sintaxis de merge()
izquierda.merge(
derecha,
how="inner",
on=None,
left_on=None,
right_on=None,
left_index=False,
right_index=False,
suffixes=("_x", "_y"),
indicator=False,
validate=None,
)| Parámetro | Qué hace |
|---|---|
derecha | El segundo DataFrame que quieres unir |
how | El tipo de unión: "inner", "left", "right", "outer" o "cross" |
on | La columna o la lista de columnas que tienen las dos tablas |
left_on / right_on | Las columnas clave cuando tienen nombres distintos en cada tabla |
left_index / right_index | Usa el índice como clave en lugar de una columna |
suffixes | Los sufijos de las columnas repetidas que no son clave |
indicator | Añade la columna _merge con el origen de cada fila |
validate | Comprueba la relación: "one_to_one", "one_to_many", "many_to_one" |
Tipos de merge: inner, left, right, outer y cross
Con las tablas del ejemplo, 3 clientes (ids 1, 2 y 3) y 4 pedidos (ids 1, 1, 3 y 4):
how | Qué filas conserva | Filas del resultado |
|---|---|---|
"inner" | Solo las claves que están en las dos tablas | 3 |
"left" | Todas las de la izquierda, con NaN si no hay pareja | 4 |
"right" | Todas las de la derecha, con NaN si no hay pareja | 4 |
"outer" | Todas las de las dos tablas | 5 |
"cross" | Cada fila de la izquierda con cada fila de la derecha | 12 |
El left es el más usado, porque conserva toda tu tabla principal:
print(clientes.merge(pedidos, on="id", how="left")) id nombre total
0 1 Ana 50.0
1 1 Ana 20.0
2 2 Luis NaN
3 3 Marta 80.0La columna total pasa a ser decimal porque NaN es un número decimal en pandas.
Ejemplos de merge() en pandas
Unir columnas con nombres distintos
ventas = pd.DataFrame({"cliente_id": [1, 3], "importe": [100, 60]})
resultado = clientes.merge(ventas, left_on="id", right_on="cliente_id")
print(resultado.drop(columns="cliente_id")) id nombre importe
0 1 Ana 100
1 3 Marta 60Con left_on y right_on las dos columnas clave se quedan en el resultado. Borra la que sobra con drop().
Unir por varias columnas
ventas = pd.DataFrame({"tienda": ["Centro", "Centro", "Norte"],
"mes": ["ene", "feb", "ene"],
"ventas": [100, 120, 90]})
gastos = pd.DataFrame({"tienda": ["Centro", "Norte"],
"mes": ["ene", "ene"],
"gastos": [40, 30]})
print(ventas.merge(gastos, on=["tienda", "mes"], how="left")) tienda mes ventas gastos
0 Centro ene 100 40.0
1 Centro feb 120 NaN
2 Norte ene 90 30.0Columnas repetidas: _x, _y y suffixes
precios_2025 = pd.DataFrame({"producto": ["Café", "Té"], "precio": [2.5, 2.0]})
precios_2026 = pd.DataFrame({"producto": ["Café", "Té"], "precio": [2.8, 2.1]})
print(precios_2025.merge(precios_2026, on="producto", suffixes=("_2025", "_2026"))) producto precio_2025 precio_2026
0 Café 2.5 2.8
1 Té 2.0 2.1Sin suffixes, las columnas se llamarían precio_x y precio_y.
Saber de qué tabla viene cada fila
todo = clientes.merge(pedidos, on="id", how="left", indicator=True)
sin_pedidos = todo[todo["_merge"] == "left_only"]
print(sin_pedidos) id nombre total _merge
2 2 Luis NaN left_onlyindicator=True añade la columna _merge con both, left_only o right_only. Es la forma más rápida de encontrar registros sin pareja.
Unir por el índice
clientes_idx = clientes.set_index("id")
ciudades = pd.DataFrame({"ciudad": ["Madrid", "Lima"]}, index=[1, 3])
print(clientes_idx.join(ciudades)) nombre ciudad
id
1 Ana Madrid
2 Luis NaN
3 Marta Limajoin() une por el índice y hace un left por defecto. Con merge() obtienes lo mismo usando left_index=True y right_index=True.
