Skip to content
Temas
Pandas
Pandas Concat: How to Concatenate DataFrames in Python

Pandas Concat: Cómo concatenar DataFrames en Python

Updated on

Los datos del mundo real rara vez se encuentran en un solo archivo. Usted extrae las ventas de enero de un CSV, las de febrero de otro y los objetivos del Q1 de un tercero. Hace scraping de múltiples páginas web en DataFrames separados. Divide un conjunto de datos grande para procesamiento paralelo y necesita volver a ensamblar las piezas. En todos los casos, necesita una forma confiable de combinar DataFrames sin perder filas, desordenar columnas o corromper su índice.

La función pandas concat (pd.concat()) es la herramienta estándar para esta tarea. Apila DataFrames verticalmente (agregando filas) u horizontalmente (agregando columnas), maneja columnas diferentes con elegancia y escala a cualquier cantidad de DataFrames en una sola llamada. Esta guía cubre cada parámetro que necesita, con ejemplos de código funcionales que puede pegar directamente en su notebook.

📚

Qué hace pd.concat() -- Sintaxis básica

pd.concat() toma una lista (o diccionario) de DataFrames y los une a lo largo de un eje especificado. Piense en ello como apilar bloques de construcción -- verticalmente para agregar más filas, o lado a lado para agregar más columnas.

import pandas as pd
 
result = pd.concat(
    objs,              # list or dict of DataFrames
    axis=0,            # 0 = vertical (rows), 1 = horizontal (columns)
    join='outer',      # 'outer' or 'inner'
    ignore_index=False,
    keys=None,
    sort=False,
    verify_integrity=False
)

Parámetros clave de un vistazo

ParámetroDescripciónPredeterminado
objsUna lista o diccionario de DataFrames (o Series) para concatenarRequerido
axis0 para apilar filas (vertical), 1 para apilar columnas (horizontal)0
join'outer' conserva todas las columnas; 'inner' conserva solo las columnas compartidas'outer'
ignore_indexSi es True, restablece el índice a 0, 1, 2, ... en el resultadoFalse
keysEtiquetas para identificar de qué DataFrame original proviene cada filaNone
sortOrdenar el eje de no concatenación (nombres de columnas para axis=0)False
verify_integrityLanzar error si el resultado tiene valores de índice duplicadosFalse

Datos de ejemplo para todos los ejemplos

Todos los ejemplos a continuación utilizan estos DataFrames:

import pandas as pd
 
df_jan = pd.DataFrame({
    'product': ['Widget', 'Gadget', 'Sprocket'],
    'units_sold': [150, 200, 80],
    'revenue': [1500, 3000, 960]
})
 
df_feb = pd.DataFrame({
    'product': ['Widget', 'Gadget', 'Sprocket'],
    'units_sold': [170, 180, 95],
    'revenue': [1700, 2700, 1140]
})
 
print(df_jan)
print(df_feb)

Salida:

    product  units_sold  revenue
0    Widget         150     1500
1    Gadget         200     3000
2  Sprocket          80      960

    product  units_sold  revenue
0    Widget         170     1700
1    Gadget         180     2700
2  Sprocket          95     1140

Concatenar DataFrames verticalmente (axis=0)

La concatenación vertical es el caso de uso más común. Apila un DataFrame encima de otro, agregando filas. Esto es lo que usa cuando tiene archivos mensuales, resultados por lotes o cualquier dato dividido en múltiples tablas con las mismas columnas.

combined = pd.concat([df_jan, df_feb])
print(combined)

Salida:

    product  units_sold  revenue
0    Widget         150     1500
1    Gadget         200     3000
2  Sprocket          80      960
0    Widget         170     1700
1    Gadget         180     2700
2  Sprocket          95     1140

Observe el índice: ambos DataFrames mantuvieron sus valores de índice originales (0, 1, 2), por lo que el resultado tiene valores de índice duplicados. Esto generalmente no es lo que desea. La solución es el parámetro ignore_index, que se cubre a continuación.

El parámetro ignore_index -- Restablecer el índice

Establecer ignore_index=True descarta el índice original y asigna un nuevo índice secuencial comenzando desde 0:

combined = pd.concat([df_jan, df_feb], ignore_index=True)
print(combined)

Salida:

    product  units_sold  revenue
0    Widget         150     1500
1    Gadget         200     3000
2  Sprocket          80      960
3    Widget         170     1700
4    Gadget         180     2700
5  Sprocket          95     1140

Cuándo usarlo: Casi siempre al concatenar verticalmente. A menos que su índice contenga información significativa (como marcas de tiempo o IDs únicos), restablézcalo para evitar confusiones posteriores.

El parámetro keys -- Crear un índice jerárquico

El parámetro keys agrega un nivel al índice que etiqueta de qué fuente proviene cada fila. Esto crea un MultiIndex (índice jerárquico):

combined = pd.concat([df_jan, df_feb], keys=['January', 'February'])
print(combined)

Salida:

               product  units_sold  revenue
January  0      Widget         150     1500
         1      Gadget         200     3000
         2    Sprocket          80      960
February 0      Widget         170     1700
         1      Gadget         180     2700
         2    Sprocket          95     1140

Luego puede seleccionar datos de una fuente específica usando .loc:

# Get only January data
jan_data = combined.loc['January']
print(jan_data)

Salida:

    product  units_sold  revenue
0    Widget         150     1500
1    Gadget         200     3000
2  Sprocket          80      960

Cuándo usarlo: Use keys cuando necesite rastrear a qué DataFrame original pertenece cada fila -- por ejemplo, datos de diferentes experimentos, períodos de tiempo o fuentes de datos.

Concatenar horizontalmente (axis=1) -- Lado a lado

Establecer axis=1 coloca los DataFrames uno al lado del otro, agregando columnas. Pandas alinea las filas por sus valores de índice.

targets = pd.DataFrame({
    'target_units': [160, 190, 90],
    'target_revenue': [1600, 2850, 1080]
})
 
result = pd.concat([df_jan, targets], axis=1)
print(result)

Salida:

    product  units_sold  revenue  target_units  target_revenue
0    Widget         150     1500           160            1600
1    Gadget         200     3000           190            2850
2  Sprocket          80      960            90            1080

Esto funciona correctamente porque ambos DataFrames comparten el mismo índice (0, 1, 2). Si los índices no se alinean, obtendrá valores NaN para las filas que no coinciden:

df_a = pd.DataFrame({'value_a': [10, 20, 30]}, index=[0, 1, 2])
df_b = pd.DataFrame({'value_b': [40, 50, 60]}, index=[1, 2, 3])
 
result = pd.concat([df_a, df_b], axis=1)
print(result)

Salida:

   value_a  value_b
0     10.0      NaN
1     20.0     40.0
2     30.0     50.0
3      NaN     60.0

La fila 0 no tiene value_b (no hay índice correspondiente en df_b), y la fila 3 no tiene value_a (no hay índice correspondiente en df_a).

El parámetro join -- Inner vs Outer

El parámetro join controla qué sucede cuando los DataFrames tienen diferentes columnas (para axis=0) o diferentes valores de índice (para axis=1).

outer join (predeterminado) -- Conservar todo

df_with_extra = pd.DataFrame({
    'product': ['Widget', 'Gadget'],
    'units_sold': [200, 250],
    'region': ['East', 'West']
})
 
result = pd.concat([df_jan, df_with_extra], join='outer', ignore_index=True)
print(result)

Salida:

    product  units_sold  revenue region
0    Widget         150   1500.0    NaN
1    Gadget         200   3000.0    NaN
2  Sprocket          80    960.0    NaN
3    Widget         200      NaN   East
4    Gadget         250      NaN   West

Todas las columnas de ambos DataFrames aparecen. Los valores faltantes se llenan con NaN.

inner join -- Conservar solo columnas compartidas

result = pd.concat([df_jan, df_with_extra], join='inner', ignore_index=True)
print(result)

Salida:

   product  units_sold
0   Widget         150
1   Gadget         200
2 Sprocket          80
3   Widget         200
4   Gadget         250

Solo sobreviven las columnas que existen en ambos DataFrames. La columna revenue (ausente en df_with_extra) y la columna region (ausente en df_jan) se eliminan.

Cuándo usar inner join: Cuando desea un resultado limpio sin valores NaN y está dispuesto a perder columnas que no aparecen en todos los DataFrames.

Concatenar una lista de DataFrames

Una de las mayores ventajas de pd.concat() sobre otros métodos de combinación es que maneja cualquier cantidad de DataFrames en una sola llamada. Este es el patrón estándar para combinar archivos cargados en un bucle:

import pandas as pd
 
# Simulate loading monthly CSV files
months = {
    'Jan': {'product': ['Widget', 'Gadget'], 'units': [150, 200]},
    'Feb': {'product': ['Widget', 'Gadget'], 'units': [170, 180]},
    'Mar': {'product': ['Widget', 'Gadget'], 'units': [190, 210]},
}
 
dfs = []
for month, data in months.items():
    df = pd.DataFrame(data)
    df['month'] = month
    dfs.append(df)
 
all_data = pd.concat(dfs, ignore_index=True)
print(all_data)

Salida:

  product  units month
0  Widget    150   Jan
1  Gadget    200   Jan
2  Widget    170   Feb
3  Gadget    180   Feb
4  Widget    190   Mar
5  Gadget    210   Mar

Este patrón -- construir una lista de DataFrames y luego llamar a concat una vez al final -- es mucho más rápido que agregar un DataFrame a la vez en un bucle. Cada append crea una copia completa, pero una sola llamada a pd.concat() asigna memoria una sola vez.

concat vs merge vs append -- Tabla comparativa

Pandas ofrece varias formas de combinar DataFrames. Elegir la correcta depende de cómo desea combinarlos:

Característicapd.concat()pd.merge()DataFrame.append()
Uso principalApilar DataFrames (filas o columnas)Unir por valores de columna compartidos (como SQL)Agregar filas a un DataFrame
Número de entradasCualquier cantidad a la vezDos a la vezDos a la vez
Lógica de coincidenciaAlinea por índice (o nombres de columna)Coincide por valores de columna claveAlinea por nombres de columna
Tipos de joinouter, innerinner, left, right, outer, crossSolo outer
Comportamiento predeterminadoOuter join, apilar verticalmenteInner join en columnas compartidasOuter join, agregar filas
Mejor paraCombinar archivos mensuales, resultados por lotes, tablas con el mismo esquemaJoins relacionales (clientes + pedidos)Obsoleto desde pandas 2.0
RendimientoRápido para muchos DataFramesOptimizado para joins de dos tablasLento (copia datos en cada llamada)

Cuándo usar cada uno

  • Use pd.concat() cuando sus DataFrames comparten la misma estructura (mismas columnas) y desea apilarlos. También úselo para concatenación horizontal al alinear por índice.
  • Use pd.merge() cuando necesite hacer coincidir filas basándose en valores de columna -- como unir una tabla de ventas con una tabla de productos por product_id. Consulte nuestra guía de pandas merge para más detalles.
  • Evite DataFrame.append() -- fue obsoleto en pandas 1.4 y eliminado en pandas 2.0. Use pd.concat([df1, df2]) en su lugar.

Errores comunes y soluciones

1. Las columnas no se alinean

Al concatenar DataFrames con diferentes nombres de columna, el outer join predeterminado llena los valores faltantes con NaN. Si no esperaba esto, verifique los nombres de sus columnas:

# Diagnose: compare column names
print(df1.columns.tolist())
print(df2.columns.tolist())
 
# Fix: rename columns to match before concatenating
df2 = df2.rename(columns={'sales': 'revenue', 'qty': 'units_sold'})
combined = pd.concat([df1, df2], ignore_index=True)

2. Discrepancias de tipos de datos después de la concatenación

Si un DataFrame almacena una columna como int64 y otro como float64, pandas convierte a float. Peor aún, si uno la almacena como string, obtiene una columna con dtype object:

# Check dtypes after concat
combined = pd.concat([df1, df2], ignore_index=True)
print(combined.dtypes)
 
# Fix: cast before concatenating
df2['units_sold'] = df2['units_sold'].astype(int)
combined = pd.concat([df1, df2], ignore_index=True)

3. Valores de índice duplicados

Sin ignore_index=True, la concatenación vertical preserva los índices originales, lo que lleva a valores duplicados. Esto causa problemas con las búsquedas .loc:

combined = pd.concat([df1, df2])
# combined.loc[0] returns TWO rows, not one
 
# Fix option 1: use ignore_index
combined = pd.concat([df1, df2], ignore_index=True)
 
# Fix option 2: use verify_integrity to catch the issue early
combined = pd.concat([df1, df2], verify_integrity=True)  # raises ValueError

4. Concatenación accidental a lo largo del eje equivocado

Si su resultado tiene el doble de columnas en lugar del doble de filas (o viceversa), verifique el parámetro axis:

# Wrong: this adds columns side by side
wrong = pd.concat([df1, df2], axis=1)
 
# Right: this stacks rows vertically
right = pd.concat([df1, df2], axis=0)

Visualice sus DataFrames concatenados con PyGWalker

Después de concatenar datos de múltiples fuentes, a menudo necesita verificar el resultado y explorar patrones en el conjunto de datos combinado. En lugar de escribir código de gráficos manual con matplotlib o seaborn, puede usar PyGWalker (opens in a new tab) -- una biblioteca de Python de código abierto que convierte cualquier DataFrame de pandas en una interfaz de exploración visual interactiva, similar a Tableau, directamente dentro de Jupyter Notebook.

import pandas as pd
import pygwalker as pyg
 
# Combine monthly sales data
df_jan = pd.DataFrame({
    'product': ['Widget', 'Gadget', 'Sprocket'],
    'units_sold': [150, 200, 80],
    'revenue': [1500, 3000, 960],
    'month': ['Jan', 'Jan', 'Jan']
})
 
df_feb = pd.DataFrame({
    'product': ['Widget', 'Gadget', 'Sprocket'],
    'units_sold': [170, 180, 95],
    'revenue': [1700, 2700, 1140],
    'month': ['Feb', 'Feb', 'Feb']
})
 
combined = pd.concat([df_jan, df_feb], ignore_index=True)
 
# Launch interactive visualization
walker = pyg.walk(combined)

Con PyGWalker, puede arrastrar product al eje x y revenue al eje y, luego dividir por month para comparar instantáneamente las tendencias de ingresos entre períodos -- sin necesidad de código de gráficos. Puede crear gráficos de barras, diagramas de dispersión, gráficos de líneas y más simplemente arrastrando campos. Es especialmente útil para verificar que su concatenación funcionó correctamente y que los datos de diferentes fuentes se alinean como se esperaba.

Instale PyGWalker con pip install pygwalker, o pruébelo en Google Colab (opens in a new tab) o Kaggle (opens in a new tab).

FAQ

¿Cuál es la diferencia entre pandas concat y merge?

pd.concat() apila DataFrames verticalmente (agregando filas) u horizontalmente (agregando columnas) alineando por el índice. pd.merge() une dos DataFrames haciendo coincidir valores en columnas específicas, como un SQL JOIN. Use concat cuando sus DataFrames tengan las mismas columnas y quiera combinar filas. Use merge cuando necesite hacer coincidir filas basándose en una columna clave compartida.

¿pd.concat() modifica los DataFrames originales?

No. pd.concat() siempre devuelve un nuevo DataFrame. Los DataFrames originales permanecen sin cambios. Esto es consistente con el principio de diseño de pandas de que las operaciones devuelven nuevos objetos en lugar de modificar los datos en su lugar.

¿Cómo concateno DataFrames con diferentes columnas?

Use pd.concat() con el valor predeterminado join='outer' -- mantiene todas las columnas de todos los DataFrames y llena los valores faltantes con NaN. Si solo quiere columnas que aparezcan en todos los DataFrames, establezca join='inner'. También puede renombrar columnas antes de concatenar para asegurar la alineación.

¿Es pd.concat() más rápido que DataFrame.append()?

Sí. DataFrame.append() fue obsoleto en pandas 1.4 y eliminado en pandas 2.0. Llamaba internamente a pd.concat() pero creaba una copia en cada llamada. Al combinar muchos DataFrames, recopilarlos en una lista y llamar a pd.concat() una vez es significativamente más rápido porque asigna memoria una sola vez.

¿Cómo restablezco el índice después de la concatenación?

Pase ignore_index=True a pd.concat(): pd.concat([df1, df2], ignore_index=True). Esto reemplaza los valores de índice originales con un nuevo índice secuencial comenzando desde 0. Alternativamente, llame a .reset_index(drop=True) en el resultado.

Conclusión

La función pandas concat() es la herramienta preferida para combinar DataFrames que comparten la misma estructura. Aquí están los puntos clave:

  • Concatenación vertical (axis=0) apila filas y es el caso de uso más común -- ideal para combinar archivos mensuales, resultados por lotes o conjuntos de datos divididos.
  • Concatenación horizontal (axis=1) coloca DataFrames lado a lado, alineando por el índice.
  • Use ignore_index=True para obtener un índice secuencial limpio (recomendado en la mayoría de los casos).
  • Use keys para crear un índice jerárquico que rastrea de qué fuente proviene cada fila.
  • El parámetro join controla cómo se manejan las columnas que no coinciden: 'outer' conserva todo, 'inner' conserva solo las columnas compartidas.
  • Siempre recopile DataFrames en una lista y llame a pd.concat() una vez, en lugar de agregar en un bucle.
  • Use pd.merge() cuando necesite joins estilo SQL en valores de columna.

Una vez que sus datos están concatenados, herramientas como PyGWalker (opens in a new tab) le permiten explorar visualmente el resultado combinado sin escribir código de gráficos, haciendo más rápido verificar su pipeline de datos y descubrir patrones entre fuentes.

📚