Introducci贸n
Contenido
Pandas proporciona una amplia gama de m茅todos y funciones para manipular datos, incluida la fusi贸n de DataFrames. Fusionar DataFrames le permite crear un nuevo DataFrame sin modificar la fuente de datos original o alterar la fuente de datos original.
Si est谩 familiarizado con SQL o un tipo similar de datos tabulares, probablemente est茅 familiarizado con el t茅rmino join
, lo que significa combinar DataFrames para formar un nuevo DataFrame. Si eres un principiante, puede ser dif铆cil comprender completamente los tipos de uni贸n (interna, externa, izquierda, derecha). En este tutorial repasaremos los tipos de combinaci贸n con ejemplos.
Nuestro enfoque principal ser铆a el uso de merge()
y concat()
funciones. Sin embargo, discutiremos otros m茅todos de fusi贸n para brindarle tantas alternativas pr谩cticas como sea posible.
Para este tutorial, usamos Pandas versi贸n 1.1.4 y NumPy versi贸n 1.19.4.
Para su comodidad, aqu铆 est谩 la tabla de contenido:
- Fusionar DataFrames usando merge ()
- Fusionar DataFrames usando join ()
- Combinar DataFrames usando append ()
- Fusionar DataFrames usando concat ()
- Fusionar DataFrames usando combine_first () y update ()
Fusionar DataFrames usando merge ()
Comencemos por configurar nuestros DataFrames, que usaremos para el resto del tutorial.
df1
incluir谩 nuestra lista de usuarios imaginaria con nombres, correos electr贸nicos e ID.
import pandas as pd
df1 = pd.DataFrame({'user_id': ['id001', 'id002', 'id003', 'id004', 'id005', 'id006', 'id007'],
'first_name': ['Rivi', 'Wynnie', 'Kristos', 'Madalyn', 'Tobe', 'Regan', 'Kristin'],
'last_name': ['Valti', 'McMurty', 'Ivanets', 'Max', 'Riddich', 'Huyghe', 'Illis'],
'email': ['[email聽protected]', '[email聽protected]', '[email聽protected]',
'[email聽protected]', '[email聽protected]', '[email聽protected]', '[email聽protected]']
})
Al dise帽ar bases de datos, se considera una buena pr谩ctica mantener la configuraci贸n del perfil (como el color de fondo, el enlace de la imagen del avatar, el tama帽o de fuente, etc.) en una tabla separada de los datos del usuario (correo electr贸nico, fecha de adici贸n, etc.) Estas tablas pueden tener una relaci贸n de uno a uno.
Para simular este escenario haremos lo mismo creando df2
con URL de imagen e ID de usuario:
df2 = pd.DataFrame({'user_id': ['id001', 'id002', 'id003', 'id004', 'id005'],
'image_url': ['http://example.com/img/id001.png', 'http://example.com/img/id002.jpg',
'http://example.com/img/id003.bmp', 'http://example.com/img/id004.jpg',
'http://example.com/img/id005.png']
})
As铆 es como se ven nuestros DataFrames:
# df1
user_id first_name last_name email
0 id001 Rivi Valti [email聽protected]
1 id002 Wynnie McMurty [email聽protected]
2 id003 Kristos Ivanets [email聽protected]
3 id004 Madalyn Max [email聽protected]
4 id005 Tobe Riddich [email聽protected]
5 id006 Regan Huyghe [email聽protected]
6 id007 Kristin Illis [email聽protected]
#df2
user_id image_url
0 id001 http://example.com/img/id001.png
1 id002 http://example.com/img/id002.jpg
2 id003 http://example.com/img/id003.bmp
3 id004 http://example.com/img/id004.jpg
4 id005 http://example.com/img/id005.png
Combinemos estos DataFrames con el merge()
funci贸n. Primero, eche un vistazo a todas las opciones que esta funci贸n puede aceptar de un vistazo:
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=('_x', '_y'), copy=True, indicator=False,
validate=None)
La mayor铆a de estas opciones tienen un valor predeterminado, excepto el izquierda y derecho. Estos dos par谩metros son los nombres de los DataFrames que fusionaremos. La funci贸n en s铆 devolver谩 un nuevo DataFrame, que almacenaremos en df3_merged
variable.
Ingresa el siguiente c贸digo en tu shell de Python:
df3_merged = pd.merge(df1, df2)
Dado que nuestros dos DataFrames tienen la columna user_id
con el mismo nombre, el merge()
La funci贸n une autom谩ticamente dos tablas que coinciden con esa clave. Si tuvi茅ramos dos columnas con diferentes nombres, podr铆amos usar left_on='left_column_name'
y right_on='right_column_name'
para especificar claves en ambos DataFrames expl铆citamente.
Vamos a imprimir el df3_merged
variable para ver su contenido:
user_id first_name last_name email image_url
0 id001 Rivi Valti [email聽protected] http://example.com/img/id001.png
1 id002 Wynnie McMurty [email聽protected] http://example.com/img/id002.jpg
2 id003 Kristos Ivanets [email聽protected] http://example.com/img/id003.bmp
3 id004 Madalyn Max [email聽protected] http://example.com/img/id004.jpg
4 id005 Tobe Riddich [email聽protected] http://example.com/img/id005.png
Notar谩s que df3_merged
tiene solo 5 filas, mientras que el df1 original ten铆a 7. 驴Por qu茅?
Cuando el valor predeterminado de la how
el par谩metro est谩 establecido en inner
, se genera un nuevo DataFrame a partir de la intersecci贸n de los DataFrames izquierdo y derecho. Por lo tanto, si un user_id
falta en una de las tablas, no estar铆a en el DataFrame combinado.
Esto seguir铆a siendo cierto incluso si se intercambiaran los lugares de las filas izquierda y derecha:
df3_merged = pd.merge(df2, df1)
Los resultados siguen siendo:
user_id image_url first_name last_name email
0 id001 http://example.com/img/id001.png Rivi Valti [email聽protected]
1 id002 http://example.com/img/id002.jpg Wynnie McMurty [email聽protected]
2 id003 http://example.com/img/id003.bmp Kristos Ivanets [email聽protected]
3 id004 http://example.com/img/id004.jpg Madalyn Max [email聽protected]
4 id005 http://example.com/img/id005.png Tobe Riddich [email聽protected]
Usuarios con ID 'id006'
y 'id007'
no forman parte de los DataFrames fusionados ya que no se cruzan en ambas tablas.
Sin embargo, hay ocasiones en las que queremos usar uno de los DataFrame como el DataFrame principal e incluir todas las filas incluso si no todas se cruzan entre s铆. Es decir, tener todos nuestros usuarios, mientras que el image_url
es opcional.
驴C贸mo? Mediante el uso merge()
, podemos pasar el 'left'
argumento a la how
par谩metro:
df_left_merge = pd.merge(df1, df2, how='left')
print(df_left_merge)
Con una combinaci贸n izquierda, hemos incluido todos los elementos del DataFrame izquierdo (df1
) y todos los elementos del DataFrame correcto (df2
). Ejecutar el c贸digo anterior mostrar铆a esto:
user_id first_name last_name email image_url
0 id001 Rivi Valti [email聽protected] http://example.com/img/id001.png
1 id002 Wynnie McMurty [email聽protected] http://example.com/img/id002.jpg
2 id003 Kristos Ivanets [email聽protected] http://example.com/img/id003.bmp
3 id004 Madalyn Max [email聽protected] http://example.com/img/id004.jpg
4 id005 Tobe Riddich [email聽protected] http://example.com/img/id005.png
5 id006 Regan Huyghe [email聽protected] NaN
6 id007 Kristin Illis [email聽protected] NaN
Las celdas que no tienen ning煤n valor coincidente con el DataFrame izquierdo se rellenan con NaN
.
驴Por qu茅 no intentamos una combinaci贸n correcta? Cree el siguiente DataFrame combinado:
df_right_merge = pd.merge(df1, df2, how='right')
print(df_right_merge)
Como era de esperar, la combinaci贸n derecha devolver铆a todos los valores del DataFrame izquierdo que coincida con el DataFrame derecho:
user_id first_name last_name email image_url
0 id001 Rivi Valti [email聽protected] http://example.com/img/id001.png
1 id002 Wynnie McMurty [email聽protected] http://example.com/img/id002.jpg
2 id003 Kristos Ivanets [email聽protected] http://example.com/img/id003.bmp
3 id004 Madalyn Max [email聽protected] http://example.com/img/id004.jpg
4 id005 Tobe Riddich [email聽protected] http://example.com/img/id005.png
Como cada fila en df2
tiene un valor en df1
, esta right
unirse es similar a la inner
unirse, en este caso.
Echemos un vistazo a outer
Uniones. Para ilustrar mejor c贸mo funcionan, intercambiemos lugares de nuestros DataFrames y creemos 2 nuevas variables para las uniones izquierdas y externas:
df_left = pd.merge(df2, df1, how='left', indicator=True)
df_outer = pd.merge(df2, df1, how='outer', indicator=True)
print(df_left)
print(df_outer)
Tenga en cuenta que nuestro DataFrame izquierdo es df2
y el DataFrame correcto es df1
. Utilizando how='outer'
fusiona DataFrames que coinciden con la clave, pero tambi茅n incluye los valores que faltan o no coinciden.
Tambi茅n agregamos el indicator
bandera y ponerlo en True
para que Pandas agregue una columna adicional _merge
hasta el final de nuestro DataFrame. Esta columna nos dice si se encontr贸 una fila en el DataFrames izquierdo, derecho o en ambos.
los df_left
variable se ve as铆:
user_id image_url first_name last_name email _merge
0 id001 http://example.com/img/id001.png Rivi Valti [email聽protected] both
1 id002 http://example.com/img/id002.jpg Wynnie McMurty [email聽protected] both
2 id003 http://example.com/img/id003.bmp Kristos Ivanets [email聽protected] both
3 id004 http://example.com/img/id004.jpg Madalyn Max [email聽protected] both
4 id005 http://example.com/img/id005.png Tobe Riddich [email聽protected] both
Sin embargo, df_outer
tiene estos datos:
user_id image_url first_name last_name email _merge
0 id001 http://example.com/img/id001.png Rivi Valti [email聽protected] both
1 id002 http://example.com/img/id002.jpg Wynnie McMurty [email聽protected] both
2 id003 http://example.com/img/id003.bmp Kristos Ivanets [email聽protected] both
3 id004 http://example.com/img/id004.jpg Madalyn Max [email聽protected] both
4 id005 http://example.com/img/id005.png Tobe Riddich [email聽protected] both
5 id006 NaN Regan Huyghe [email聽protected] right_only
6 id007 NaN Kristin Illis [email聽protected] right_only
Note que en el df_outer
Marco de datos id006
y id007
solo existe en el DataFrame derecho (en este caso es df1
). Si intent谩ramos comparar las uniones izquierdas y externas sin intercambiar los lugares, obtendr铆amos los mismos resultados para ambas.
Fusionar DataFrames usando join ()
diferente a merge()
que es un m茅todo de la instancia de Pandas, join()
es un m茅todo del propio DataFrame. Esto significa que podemos usarlo como un m茅todo est谩tico en el DataFrame: DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
.
El DataFrame que llamamos join()
de ser谩 nuestro DataFrame izquierdo. El DataFrame en el other
El argumento ser铆a nuestro DataFrame correcto.
los on
El par谩metro puede tomar uno o m谩s (['key1', 'key2' ...]
) argumentos para definir la clave coincidente, mientras que how
El par谩metro toma uno de los argumentos del identificador (izquierdo, derecho, externo, interno) y se establece en left
por defecto.
Intentemos unirnos df2
a df1
:
df_join = df1.join(df2, rsuffix='_right')
print(df_join)
Como el merge()
funci贸n, la join()
La funci贸n intenta autom谩ticamente hacer coincidir las claves (columnas) con el mismo nombre. En nuestro caso, es el user_id
llave.
El c贸digo anterior imprime esto:
user_id first_name last_name email user_id_right image_url
0 id001 Rivi Valti [email聽protected] id001 http://example.com/img/id001.png
1 id002 Wynnie McMurty [email聽protected] id002 http://example.com/img/id002.jpg
2 id003 Kristos Ivanets [email聽protected] id003 http://example.com/img/id003.bmp
3 id004 Madalyn Max [email聽protected] id004 http://example.com/img/id004.jpg
4 id005 Tobe Riddich [email聽protected] id005 http://example.com/img/id005.png
5 id006 Regan Huyghe [email聽protected] NaN NaN
6 id007 Kristin Illis [email聽protected] NaN NaN
Probablemente hayas notado una “columna duplicada” llamada user_id_right
. Si no desea mostrar esa columna, puede configurar el user_id
columnas como un 铆ndice en ambas columnas para que se unan sin un sufijo:
df_join_no_duplicates = df1.set_index('user_id').join(df2.set_index('user_id'))
print(df_join_no_duplicates)
Al hacerlo, nos estamos deshaciendo de la user_id
columna y configur谩ndola como la columna de 铆ndice. Esto nos proporciona un DataFrame resultante m谩s limpio:
first_name last_name email image_url
user_id
id001 Rivi Valti [email聽protected] http://example.com/img/id001.png
id002 Wynnie McMurty [email聽protected] http://example.com/img/id002.jpg
id003 Kristos Ivanets [email聽protected] http://example.com/img/id003.bmp
id004 Madalyn Max [email聽protected] http://example.com/img/id004.jpg
id005 Tobe Riddich [email聽protected] http://example.com/img/id005.png
id006 Regan Huyghe [email聽protected] NaN
id007 Kristin Illis [email聽protected] NaN
Combinar DataFrames usando append ()
Como apunta la documentaci贸n oficial de Pandas, desde concat()
y append()
Los m茅todos devuelven nuevas copias de DataFrames, el uso excesivo de estos m茅todos puede afectar el rendimiento de su programa.
Agregar es muy 煤til cuando desea fusionar dos DataFrames en el eje de fila 煤nicamente. Esto significa que en lugar de hacer coincidir los datos en sus columnas, queremos un nuevo DataFrame que contenga todas las filas de 2 DataFrames.
Vamos a a帽adir df2
a df1
e imprime los resultados:
df_append = df1.append(df2, ignore_index=True)
print(df_append)
Utilizando append()
no coincidir谩 con DataFrames en ninguna clave. Simplemente agregar谩 el otro DataFrame al primero y devolver谩 una copia del mismo. Si las formas de DataFrames no coinciden, Pandas reemplazar谩 cualquier celda no coincidente con un NaN.
El resultado para agregar los dos DataFrames se ve as铆:
user_id first_name last_name email image_url
0 id001 Rivi Valti [email聽protected] NaN
1 id002 Wynnie McMurty [email聽protected] NaN
2 id003 Kristos Ivanets [email聽protected] NaN
3 id004 Madalyn Max [email聽protected] NaN
4 id005 Tobe Riddich [email聽protected] NaN
5 id006 Regan Huyghe [email聽protected] NaN
6 id007 Kristin Illis [email聽protected] NaN
7 id001 NaN NaN NaN http://example.com/img/id001.png
8 id002 NaN NaN NaN http://example.com/img/id002.jpg
9 id003 NaN NaN NaN http://example.com/img/id003.bmp
10 id004 NaN NaN NaN http://example.com/img/id004.jpg
11 id005 NaN NaN NaN http://example.com/img/id005.png
La mayor铆a de los usuarios eligen concat()
sobre el append()
ya que tambi茅n proporciona la opci贸n de eje y coincidencia de claves.
Fusionar DataFrames usando concat ()
La concatenaci贸n es un poco m谩s flexible en comparaci贸n con merge()
y join()
ya que nos permite combinar DataFrames verticalmente (en filas) u horizontalmente (en columnas).
La compensaci贸n es que se descartar谩n los datos que no coincidan. Aqu铆 est谩 la funci贸n completa con los par谩metros:
pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None,
levels=None, names=None, verify_integrity=False, sort=False, copy=True)
A continuaci贸n, se muestran los par谩metros m谩s utilizados para concat()
funci贸n:
objs
es la lista de objetos DataFrame ([df1, df2, …]) para ser concatenadosaxis
define la direcci贸n de la concatenaci贸n,0
para filas y1
para columnajoin
puede serinner
(intersecci贸n) oouter
(Uni贸n)ignore_index
por defecto establecido enFalse
que permite que los valores de 铆ndice permanezcan como estaban en los DataFrames originales, puede causar valores de 铆ndice duplicados. Si se establece enTrue
, ignorar谩 los valores originales y reasignar谩 valores de 铆ndice en orden secuencialkeys
nos permite construir un 铆ndice jer谩rquico. Piense en ello como otro nivel del 铆ndice que se adjunta en la parte exterior izquierda del DataFrame que nos ayuda a distinguir los 铆ndices cuando los valores no son 煤nicos.
Creemos un nuevo DataFrame con los mismos tipos de columna que el df2, pero este incluye el image_url
para id006
y id007
:
df2_addition = pd.DataFrame({'user_id': ['id006', 'id007'],
'image_url': ['http://example.com/img/id006.png',
'http://example.com/img/id007.jpg']
})
Para unirse df2
y df2_addition
por filas, podemos pasarlos en una lista como el objs
y asigne el DataFrame resultante a una nueva variable:
df_row_concat = pd.concat([df2, df2_addition])
print(df_row_concat)
Completamos con 茅xito los valores faltantes:
user_id image_url
0 id001 http://example.com/img/id001.png
1 id002 http://example.com/img/id002.jpg
2 id003 http://example.com/img/id003.bmp
3 id004 http://example.com/img/id004.jpg
4 id005 http://example.com/img/id005.png
0 id006 http://example.com/img/id006.png
1 id007 http://example.com/img/id007.jpg
Sin embargo, eche un vistazo a los 铆ndices de la columna m谩s a la izquierda. Los 铆ndices 0
y 1
est谩n repitiendo. Para obtener valores de 铆ndice completamente nuevos y 煤nicos, pasamos True
al ignore_index
par谩metro:
df_row_concat = pd.concat([df2, df2_addition], ignore_index=True)
Ahora nuestro df_row_concat
tiene valores de 铆ndice 煤nicos:
user_id image_url
0 id001 http://example.com/img/id001.png
1 id002 http://example.com/img/id002.jpg
2 id003 http://example.com/img/id003.bmp
3 id004 http://example.com/img/id004.jpg
4 id005 http://example.com/img/id005.png
5 id006 http://example.com/img/id006.png
6 id007 http://example.com/img/id007.jpg
Como mencionamos anteriormente, la concatenaci贸n puede funcionar tanto horizontal como verticalmente. Para unir dos DataFrames juntos por columnas, necesitaremos cambiar el axis
valor del predeterminado 0
a 1
:
df_column_concat = pd.concat([df1, df_row_concat], axis=1)
print(df_column_concat)
Notar谩 que no funciona como una combinaci贸n, haciendo coincidir dos tablas en una clave:
user_id first_name last_name email user_id image_url
0 id001 Rivi Valti [email聽protected] id001 http://example.com/img/id001.png
1 id002 Wynnie McMurty [email聽protected] id002 http://example.com/img/id002.jpg
2 id003 Kristos Ivanets [email聽protected] id003 http://example.com/img/id003.bmp
3 id004 Madalyn Max [email聽protected] id004 http://example.com/img/id004.jpg
4 id005 Tobe Riddich [email聽protected] id005 http://example.com/img/id005.png
5 id006 Regan Huyghe [email聽protected] id006 http://example.com/img/id006.png
6 id007 Kristin Illis [email聽protected] id007 http://example.com/img/id007.jpg
Si nuestro DataFrame correcto ni siquiera tuviera un user_id
columna, esta concatenaci贸n todav铆a devolver铆a el mismo resultado. los concat()
La funci贸n pega dos DataFrames juntos, teniendo en cuenta los valores de los 铆ndices de DataFrames y la forma de la tabla.
No hace coincidir claves como merge()
de join()
. Pruebe diferentes combinaciones de concatenaci贸n cambiando el join
par谩metro para ver las diferencias!
Fusionar DataFrames usando combine_first () y update ()
En algunos casos, es posible que desee completar los datos que faltan en su DataFrame combin谩ndolos con otro DataFrame. Al hacerlo, mantendr谩 todos los valores que no faltan en el primer DataFrame mientras reemplaza todos NaN
valores con valores disponibles no perdidos del segundo DataFrame (si hay alguno).
Para este ejemplo, importaremos NumPy para usar NaN
valores. Si instal贸 Pandas con pip
, NumPy ya deber铆a estar instalado.
Escriba el siguiente c贸digo en su shell de Python o archivo de secuencia de comandos:
import numpy as np
df_first = pd.DataFrame({'COL 1': ['X', 'X', np.nan],
'COL 2': ['X', np.nan, 'X'],
'COL 3': [np.nan, 'X', 'X']},
index=range(0, 3))
df_second = pd.DataFrame({'COL 1': [np.nan, 'O', 'O'],
'COL 2': ['O', 'O', 'O']},
index=range(0, 3))
print(df_first)
print(df_second)
los df_first
DataFrame tiene 3 columnas y 3 valores faltantes en cada una de ellas:
COL 1 COL 2 COL 3
0 X X NaN
1 X NaN X
2 NaN X X
Mientras df_second
tiene solo 2 columnas y un valor faltante en la primera columna:
COL 1 COL 2
0 NaN O
1 O O
2 O O
Nosotros podemos usar df_second
para parchear los valores faltantes en df_first
con todos los valores correspondientes:
df_tictactoe = df_first.combine_first(df_second)
print(df_tictactoe)
Como se mencion贸 anteriormente, el uso de combine_first()
el m茅todo solo reemplazar谩 NaN
valores en orden de 铆ndice, y dejar谩 todos los valores no perdidos en el primer DataFrame como est谩n:
COL 1 COL 2 COL 3
0 X X NaN
1 X O X
2 O X X
Por otro lado, si quisi茅ramos sobrescribir los valores en df_first
con los valores correspondientes de df_second
(independientemente de que sean NaN o no), usar铆amos el update()
m茅todo.
Primero agreguemos otro DataFrame a nuestro c贸digo:
df_third = pd.DataFrame({'COL 1': ['O'], 'COL 2': ['O'], 'COL 3': ['O']})
print(df_third)
La forma es (1, 3) – 1 fila y tres columnas, excluyendo el 铆ndice:
COL 1 COL 2 COL 3
0 O O O
Ahora actualice el df_first
con los valores de df_third
:
df_first.update(df_third)
print(df_first)
Tenga en cuenta que a diferencia combine_first()
, update()
no devuelve un nuevo DataFrame. Modifica el df_first
in situ, alterando los valores correspondientes:
COL 1 COL 2 COL 3
0 O O O
1 X NaN X
2 NaN X X
los overwrite
par谩metro de la update()
la funci贸n est谩 configurada en True
por defecto. Es por eso que cambia todos los valores correspondientes, en lugar de solo NaN
valores. Podemos cambiarlo a False
para reemplazar solo NaN
valores:
df_tictactoe.update(df_first, overwrite=False)
print(df_tictactoe)
Aqu铆 est谩 el estado final de nuestro df_tictactoe
Marco de datos:
COL 1 COL 2 COL 3
0 X X O
1 X O X
2 O X X
隆No solo actualizamos con 茅xito los valores, sino que tambi茅n ganamos el juego Tic-Tac-Toe!
Conclusi贸n
Pandas proporciona herramientas poderosas para fusionar DataFrames. Pero puede ser dif铆cil decidir cu谩ndo usar qu茅. Mientras que la mayor铆a de las veces merge()
la funci贸n es suficiente, en algunos casos es posible que desee utilizar concat()
para fusionar filas o usar join()
con sufijos, o deshacerse de los valores perdidos con combine_first()
y update()
. Incluso puede agregar filas de datos con append()
.
Utilice la funci贸n con la que se sienta m谩s c贸modo y que sea mejor para la tarea en cuesti贸n. 驴C贸mo te ayudar铆an estas funciones a manipular datos en Pandas?