Combinando DataFrames
Hay dos formas de juntar DataFrames y se confunden constantemente porque ambas “combinan datos”. Son conceptualmente opuestas:
merge / join concat
───────────────── ──────────────────
Une por SIGNIFICADO Une por POSICION
"¿Que comparten?" "Ponlos uno encima/lado del otro"
Como SQL JOIN Como pegar hojas de papel
Necesita keys comunes Solo necesita que quepan
Merge: union relacional
pd.merge() une dos DataFrames basandose en valores compartidos en columnas (o indices). Es el equivalente de JOIN en SQL.
El tipo de join determina que filas sobreviven:
LEFT INNER RIGHT OUTER
┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
│A │ │B │ │A │ │B │ │A │ │B │ │A │ │B │
│1 │ │1 │ │1 │ │1 │ │1 │ │1 │ │1 │ │1 │
│2 │ │1 │ │2 │ │1 │ │2 │ │2 │ │2 │ │2 │
│3 │ │2 │ └──┘ └──┘ └──┘ └──┘ │3 │ │3 │
└──┘ └──┘ └──┘ └──┘
Todas de A Solo comunes Todas de B Todas de ambos
Concat: apilado posicional
pd.concat() junta DataFrames por posicion geometrica, no por significado compartido. No busca claves comunes: simplemente coloca un DataFrame junto al otro, ya sea verticalmente o en horizontal.
El parametro axis indica que dimension crece como resultado de la operacion.
Como pensar en axis
Un DataFrame tiene dos ejes:
columna_a columna_b columna_c
↑ ↑ ↑
└──────────┴──────────┘ ← eje de columnas (axis=1)
indice → 0 │ 10 20 30
indice → 1 │ 11 21 31 ← eje de filas (axis=0)
indice → 2 │ 12 22 32
- axis=0 es el eje de las filas (el indice). Concatenar a lo largo de
axis=0significa que el indice crece: se anaden mas filas. Las columnas deben coincidir. - axis=1 es el eje de las columnas. Concatenar a lo largo de
axis=1significa que las columnas crecen: se anaden mas columnas. Los indices deben coincidir.
La trampa intuitiva
El nombre “axis” genera confusion porque parece decir “en que direccion se mueven los datos”, cuando en realidad dice “que dimension del resultado se expande”.
Una forma de recordarlo:
axis=0→ el resultado tiene mas filas que cualquiera de los inputsaxis=1→ el resultado tiene mas columnas que cualquiera de los inputs
axis=0 — apilar filas (vertical)
Dos DataFrames con las mismas columnas, uno encima del otro:
df_enero df_febrero pd.concat([df_enero, df_febrero], axis=0)
────────────── ────────────── ────────────────────────────
mes ventas mes ventas mes ventas
0 ene 10 0 feb 30 0 ene 10
1 ene 20 1 feb 40 1 ene 20
0 feb 30 ← indice se repite
1 feb 40 (usar ignore_index=True
para 0,1,2,3)
Caso de uso tipico: tienes un archivo CSV por mes y quieres un unico DataFrame con todos los meses.
axis=1 — apilar columnas (horizontal)
Dos DataFrames con el mismo indice, uno al lado del otro:
df_demograficos df_financieros pd.concat([...], axis=1)
────────────────── ──────────────── ─────────────────────────────────
nombre edad salario ciudad nombre edad salario ciudad
0 Ana 25 0 35000 CDMX 0 Ana 25 35000 CDMX
1 Carlos 32 1 52000 MTY 1 Carlos 32 52000 MTY
2 Maria 28 2 41000 GDL 2 Maria 28 41000 GDL
Condicion: los indices deben coincidir. Si el indice de df_demograficos es [0,1,2] y el de df_financieros es [0,1,3], la fila con indice 2 en demograficos y la fila con indice 3 en financieros no tendran pareja, y aparecen con NaN en las columnas del otro DataFrame.
Caso de uso tipico: tienes columnas de distintas fuentes sobre las mismas entidades (mismo indice) y quieres unirlas en un solo DataFrame.
Por que no usar concat cuando necesitas merge
Concat no verifica que los datos correspondan — solo los pega por posicion. Si el orden de las filas en df_demograficos es distinto al orden en df_financieros, los datos de Ana quedaran en la misma fila que los datos de Carlos. No hay error, solo datos incorrectos.
Cuando necesitas unir datos por un identificador comun (nombre, id, fecha), usa merge. Concat es para cuando ya sabes que las filas o columnas corresponden posicionalmente.