El post continua con la librería pandas, introduciendo las capacidades que posee para unir y/o cruzar bases de datos.
Disclaimer A: La información contenida en esta página está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional y fue construida bajo mi rol como ayudante (Teacher Assistant) de la Catedra Business Intelligence para las Finanzas.
Disclaimer B: Este post está basado en mis propios resumenes a partir de los capítulos del libro Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython, de Wes McKinney. La mayoría de los ejemplos provienen de momento del libro.
Advertencia: La página es un complemento a la cátedra y por nada la sustituye.
Pandas posee funciones capaces de unir y/o cruzar bases (Series o DataFrame) de datos basados en un conjunto lógico a nivel de columna o índice (index), estos son concat() y merge(). Para efecto de las aplicaciones se construirán tres DataFrames con nombres de actores y actrices de hollywood:
raw_data_a = {
'id': ['1', '2', '3', '4', '5'],
'nombre': ['Tom', 'Will', 'Tom', 'Jennifer', 'Charlize'],
'apellido': ['Cruise', 'Smith', 'Hanks', 'Aniston', 'Theron']}
df_a = pd.DataFrame(raw_data_a, columns = ['id', 'nombre', 'apellido'])
df_a
id nombre apellido
0 1 Tom Cruise
1 2 Will Smith
2 3 Tom Hanks
3 4 Jennifer Aniston
4 5 Charlize Theron
raw_data_b = {
'id': ['4', '5', '6', '7', '8'],
'nombre': ['Julia', 'Nicole', 'Emma', 'George', 'Al'],
'apellido': ['Roberts', 'Kidman', 'Watson', 'Clooney', 'Pacino']}
df_b = pd.DataFrame(raw_data_b, columns = ['id', 'nombre', 'apellido'])
df_b
id nombre apellido
0 4 Julia Roberts
1 5 Nicole Kidman
2 6 Emma Watson
3 7 George Clooney
4 8 Al Pacino
raw_data_c = {
'id': ['1', '2', '3', '4', '5', '7', '8', '9', '10', '11'],
'test_id': [51, 15, 15, 61, 16, 14, 15, 1, 61, 16]}
df_n = pd.DataFrame(raw_data_c, columns = ['id','test_id'])
df_n
id test_id
0 1 51
1 2 15
2 3 15
3 4 61
4 5 16
5 7 14
6 8 15
7 9 1
8 10 61
9 11 16
Recordatorio: Se puede crear un DataFrame a partir de un diccionario, en donde el nombre de la columna del DataFrame debe existir como llave en el diccionario. Caso contrario un
NaNaparecerá.
Concatenar tiene el objetivo de unir bases de datos por columna o filas. La sintaxis con los valores por defecto es:
pd.concat(objs, axis=0, join='outer', ignore_index=False, keys=None,
levels=None, names=None, verify_integrity=False, copy=True)
Considerando los DataFrames df_a y df_b, si se quiere unir por columnas:
pd.concat([df_a, df_b], axis=1)
id nombre apellido id nombre apellido
0 1 Tom Cruise 4 Julia Roberts
1 2 Will Smith 5 Nicole Kidman
2 3 Tom Hanks 6 Emma Watson
3 4 Jennifer Aniston 7 George Clooney
4 5 Charlize Theron 8 Al Pacino
Para el caso de querer unir por filas:
pd.concat([df_a, df_b], axis=0)
id nombre apellido
0 1 Tom Cruise
1 2 Will Smith
2 3 Tom Hanks
3 4 Jennifer Aniston
4 5 Charlize Theron
0 4 Julia Roberts
1 5 Nicole Kidman
2 6 Emma Watson
3 7 George Clooney
4 8 Al Pacino
Si bien cumple, hay que tener las siguientes consideraciones:
Si se concatena por columnas, va a existir nombres de columnas repetidas (en este caso), pero igual nombre/número de índice, al menos que el segundo DataFrame posean otro nombre:
id nombre apellido Id Nombre Apellido
0 1 Tom Cruise 4 Julia Roberts
1 2 Will Smith 5 Nicole Kidman
2 3 Tom Hanks 6 Emma Watson
3 4 Jennifer Aniston 7 George Clooney
4 5 Charlize Theron 8 Al Pacino
Python es case sensitive.
Si se concatena por filas, no va a existir nombres de columnas repetidas (en este caso), pero va a existir nombre/número de índice repetido. Con ignore_index=True se soluciona:
pd.concat([df_a, df_b], axis=0, ignore_index=True)
id nombre apellido
0 1 Tom Cruise
1 2 Will Smith
2 3 Tom Hanks
3 4 Jennifer Aniston
4 5 Charlize Theron
5 4 Julia Roberts
6 5 Nicole Kidman
7 6 Emma Watson
8 7 George Clooney
9 8 Al Pacino
No es necesario que posean la misma cantidad de filas, pero NaNs aparecerán con axis=1:
id nombre apellido id nombre apellido
0 1 Tom Cruise 4 Julia Roberts
1 2 Will Smith 5 Nicole Kidman
2 3 Tom Hanks 6 Emma Watson
3 4 Jennifer Aniston 7 George Clooney
4 NaN NaN NaN 8 Al Pacino
Para mayor información visitar.
El método pd.merge() realiza operaciones para bases de datos relacionales parecidos a SQL. La sintaxis es la siguiente:
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)
Cuando se trabaja con bases de datos relacionales, es importante entender:
Curiosidad:
pd.merge()tiene un desempeño mayor a su función gemela en R base (base::merge.data.frame), sin embargo, R posee actualmente la libreríadplyrcuyo espiritu nace a partir de SQL.
Para explicar el uso de pd.merge(), se va a utilizar concatenación entre el DataFrame df_a y df_b:
df_nueva = pd.concat([df_a, df_b], axis=0)
on:Si se quisiera unir el objeto DataFrame df_nueva con df_n bajo la lógica de muchos-a-muchos:
pd.merge(df_nueva, df_n, on='id')
id nombre apellido test_id
0 1 Tom Cruise 51
1 2 Will Smith 15
2 3 Tom Hanks 15
3 4 Jennifer Aniston 61
4 4 Julia Roberts 61
5 5 Charlize Theron 16
6 5 Nicole Kidman 16
7 7 George Clooney 14
8 8 Al Pacino 15
La opción on permite seleccionar la llave única en ambos DataFrame por la que se va a unir. Para más de una llave, solo es necesario agregarlo en a un lista es decir, on=['llave_1', 'llave_2'].
Si se desea tener obtener el mismo resultado anterior, se puede replicar usando las mismas llaves en las opciones left_on y right_on.
pd.merge(df_nueva, df_n, left_on='id', right_on='id')
id nombre apellido test_id
0 1 Tom Cruise 51
1 2 Will Smith 15
2 3 Tom Hanks 15
3 4 Jennifer Aniston 61
4 4 Julia Roberts 61
5 5 Charlize Theron 16
6 5 Nicole Kidman 16
7 7 George Clooney 14
8 8 Al Pacino 15
how:El argumento how determina que llave serán incluidas en la tabla resultante. Si una combinación de llaves no aparece tanto en la tabla de la izquierda (left) o derecha (right), el valor será NA.
pd.merge(df_a, df_b, on='id', how='right')
id nombre_x apellido_x nombre_y apellido_y
0 4 Jennifer Aniston Julia Roberts
1 5 Charlize Theron Nicole Kidman
2 6 NaN NaN Emma Watson
3 7 NaN NaN George Clooney
4 8 NaN NaN Al Pacino
pd.merge(df_a, df_b, on='id', how='left')
id nombre_x apellido_x nombre_y apellido_y
0 1 Tom Cruise NaN NaN
1 2 Will Smith NaN NaN
2 3 Tom Hanks NaN NaN
3 4 Jennifer Aniston Julia Roberts
4 5 Charlize Theron Nicole Kidman
La opción ‘outer’ unirá (unión) considerando todas las llaves seleccionadas:
pd.merge(df_a, df_b, on='id', how='outer')
id nombre_x apellido_x nombre_y apellido_y
0 1 Tom Cruise NaN NaN
1 2 Will Smith NaN NaN
2 3 Tom Hanks NaN NaN
3 4 Jennifer Aniston Julia Roberts
4 5 Charlize Theron Nicole Kidman
5 6 NaN NaN Emma Watson
6 7 NaN NaN George Clooney
7 8 NaN NaN Al Pacino
La opción ‘inner’ unirá (intersección) considerando solo las llaves seleccionadas que se repitan en ambas bases:
pd.merge(df_a, df_b, on='id', how='inner')
id nombre_x apellido_x nombre_y apellido_y
0 4 Jennifer Aniston Julia Roberts
1 5 Charlize Theron Nicole Kidman
suffixes:Cuando las columnas posean el mismo nombre, al aplicar pd.merge() por defecto Pandas agregará al nombre un x e y. Con suffixes se puede agregar un nombre a elección:
pd.merge(df_a, df_b, on='id', how='left', suffixes=('_left', '_right'))
id nombre_left apellido_left nombre_right apellido_right
0 1 Tom Cruise NaN NaN
1 2 Will Smith NaN NaN
2 3 Tom Hanks NaN NaN
3 4 Jennifer Aniston Julia Roberts
4 5 Charlize Theron Nicole Kidman
Con right_index y left_index se obtiene algo parecido a pd.concat([df_a, df_b], axis=1), sin embargo, como la lógica de pd.merge() es otra se agrega en este caso la columna id pero le agrega los sufijo explicados antes.
pd.merge(df_a, df_b, right_index=True, left_index=True)
id_x nombre_x apellido_x id_y nombre_y apellido_y
0 1 Tom Cruise 4 Julia Roberts
1 2 Will Smith 5 Nicole Kidman
2 3 Tom Hanks 6 Emma Watson
3 4 Jennifer Aniston 7 George Clooney
4 5 Charlize Theron 8 Al Pacino
Para mayor información visitar.
Construya los tres DataFrames utilizados en el post.
Utilizando la función pd.concat(), concatene los DataFrames df_a y df_b por columna. Denomine a este nuevo objeto df_nueva.
Utilizando la función pd.merge(), fusione los DataFrames df_nueva y df_n.
Encuentre:
La intersección entre df_a y df_b.
La union entredf_a y df_b.
Fusione los DataFrames df_a y df_b:
Por la derecha.
Por la izquierda
Cambie el nombre de las columnas generadas en (5.b) usando sufijos.
Fusiene los DataFrames df_a y df_b, a través de los índices (index).