Combinar dataframes usando pandas

julio 10, 2019



Pandas cuenta con métodos que permiten unir dataframes usando columnas, índices o la posición de los datos como referencia. Se presentan los métodos concat, join y merge.
Creado: Julio 10 de 2019
Modificado: Julio 10 de 2019
Testeado en:

- Python 3.6.4
- pandas 0.24.2
In [1]:
import pandas as pd
from IPython.display import display_html

def display_inline(*dataframes):
    df_html = [df.to_html() for df in dataframes]
    html = ''.join(df_html)
    html = html.replace('table','table style="display:inline; padding:10px"')
    display_html(html, raw=True)

pd.concat( )

Función de pandas que permite unir DataFrames o Series contenidos en una lista en un solo Dataframe o Serie.
In [2]:
df_1 = pd.DataFrame([[1, 2, 3], [2, 5, 4],[4, 2, 3]], columns=['a', 'b', 'c'])
df_2 = pd.DataFrame([[3, 5, 1], [1, 1, 4],[2, 6, 3]], columns=['a', 'd', 'e'])
df_3 = pd.DataFrame([[6, 5, 3], [3, 4, 3],[1, 7, 5]], columns=['a', 'd', 'e'])
In [3]:
dataframes = [df_1, df_2, df_3]
result = pd.concat(dataframes, sort='False', ignore_index='True')
result
Out[3]:
a b c d e
0 1 2.0 3.0 NaN NaN
1 2 5.0 4.0 NaN NaN
2 4 2.0 3.0 NaN NaN
3 3 NaN NaN 5.0 1.0
4 1 NaN NaN 1.0 4.0
5 2 NaN NaN 6.0 3.0
6 6 NaN NaN 5.0 3.0
7 3 NaN NaN 4.0 3.0
8 1 NaN NaN 7.0 5.0
La función concat genera una copia de los DataFrame de origen, por lo que cualquier modificación sobre result no afecta a df_1, df_2, df_3.
Los NaN del nuevo Dataframe se deben a que estas columnas no existen en el dataframe del cual proviene la fila, por ejemplo el elemento result.loc[0, d] es NaN porque en el DataFrame df_1 no existe la columna d.
El argumento ignore_index=True genera un índice nuevo para el DataFrame resultante en lugar de conservar los índices de los DataFrames de origen df_1, df_2, df_3.
In [4]:
dataframes = [df_1, df_2, df_3]
result = pd.concat(dataframes, sort='False', keys=['A', 'B', 'C'])
result
Out[4]:
a b c d e
A 0 1 2.0 3.0 NaN NaN
1 2 5.0 4.0 NaN NaN
2 4 2.0 3.0 NaN NaN
B 0 3 NaN NaN 5.0 1.0
1 1 NaN NaN 1.0 4.0
2 2 NaN NaN 6.0 3.0
C 0 6 NaN NaN 5.0 3.0
1 3 NaN NaN 4.0 3.0
2 1 NaN NaN 7.0 5.0
Al usar el argumento keys el DataFrame resultante genera como índice las claves dadas a cada grupo de datos y otro para cada file (multi index), lo que permite acceder rápidamente a la información proveniente de cada DataFrame de origen
In [5]:
result.loc['A']
Out[5]:
a b c d e
0 1 2.0 3.0 NaN NaN
1 2 5.0 4.0 NaN NaN
2 4 2.0 3.0 NaN NaN

Dataframe.join( )

Método de un DataFrame que permite combinar las columnas de dos dataframe usando una columna y el índice del dataframe a unir.
In [6]:
df_1 = pd.DataFrame([[1, 2, 3], [2, 5, 4],[4, 2, 3]], columns=['a', 'b', 'c'])
df_2 = pd.DataFrame([[1, 5, 1], [7, 1, 4],[2, 6, 3]], columns=['m', 'd', 'e'])
En el siguiente ejemplo se mezclará el dataframe df_2, por su índice, en el dataframe df_1, tomando como referencia la columna a. la columna a tiene en común con el índice de df_2 los números 1 y 2, por tanto los elementos que estén en la misma fila que estos números estarán en el dataframe resultante.
In [7]:
df_join = df_1.join(df_2, on='a')
In [8]:
display_inline(df_1, df_2)
print('Join:')
df_join
a b c
0 1 2 3
1 2 5 4
2 4 2 3
m d e
0 1 5 1
1 7 1 4
2 2 6 3
Join:
Out[8]:
a b c m d e
0 1 2 3 7.0 1.0 4.0
1 2 5 4 2.0 6.0 3.0
2 4 2 3 NaN NaN NaN
El mismo resultado puede lograrse usando la función merge con las siguientes especificaciones:
In [9]:
pd.merge(df_1, df_2, left_on='a', right_index=True, how='left', sort=False)
Out[9]:
a b c m d e
0 1 2 3 7.0 1.0 4.0
1 2 5 4 2.0 6.0 3.0
2 4 2 3 NaN NaN NaN

pd.merge( )

Método que permite seleccionar una columna de forma independiente para cada dataframe, el índice o un conjunto de columnas de referencia para unir dos dataframes.
merge(right[, how, on, left_on, right_on, . . . ])
In [10]:
df_1 = pd.DataFrame([[1, 2, 3], [2, 5, 4],[4, 2, 3]], columns=['a', 'b', 'c'])
df_2 = pd.DataFrame([[1, 5, 1], [7, 1, 4],[2, 6, 3]], columns=['a', 'd', 'e'])
Combinación de los dataframe df_1y df_2 tomando como referencia la columna 'a'
In [11]:
df_merge = pd.merge(df_1, df_2, on='a')
In [12]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 3
1 2 5 4
2 4 2 3
a d e
0 1 5 1
1 7 1 4
2 2 6 3
Merge:
Out[12]:
a b c d e
0 1 2 3 5 1
1 2 5 4 6 3
Este merge toma solo las filas cuyos valores de la columna 'a' se encuentran en ambos DataFrame.
Si se quiere considerar todos los valores de la columna 'a' que no están en los dos dataframe, como el $3$ y $4$, usa el argumento how = 'outer'.
In [13]:
df_merge = pd.merge(df_1, df_2, on='a', how='outer')
In [14]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 3
1 2 5 4
2 4 2 3
a d e
0 1 5 1
1 7 1 4
2 2 6 3
Merge:
Out[14]:
a b c d e
0 1 2.0 3.0 5.0 1.0
1 2 5.0 4.0 6.0 3.0
2 4 2.0 3.0 NaN NaN
3 7 NaN NaN 1.0 4.0
Para tomar todos los valores de la columna en común de uno de los dataframe, se usan en el argumento how los métodos 'left' o 'right', para tomar todos los valores del primer o del segundo dataframe respectivamente.
In [15]:
df_merge = pd.merge(df_1, df_2, on='a', how='left')
In [16]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 3
1 2 5 4
2 4 2 3
a d e
0 1 5 1
1 7 1 4
2 2 6 3
Merge:
Out[16]:
a b c d e
0 1 2 3 5.0 1.0
1 2 5 4 6.0 3.0
2 4 2 3 NaN NaN
In [17]:
df_merge = pd.merge(df_1, df_2, on='a', how='right')
In [18]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 3
1 2 5 4
2 4 2 3
a d e
0 1 5 1
1 7 1 4
2 2 6 3
Merge:
Out[18]:
a b c d e
0 1 2.0 3.0 5 1
1 2 5.0 4.0 6 3
2 7 NaN NaN 1 4
Al realizar un merge de dos dataframe con varias columnas en común, que no son usadas como columna de merge, estas se renombran automáticamente, de forma que en el dataframe resultante no hay columnas con igual nombre.
In [19]:
df_1 = pd.DataFrame([[1,2,3], [2,5,4],[4,2,3]], columns=['a', 'b', 'c'])
df_2 = pd.DataFrame([[3,5,1], [1,1,4],[2,6,3]], columns=['a', 'd', 'c'])
In [20]:
df_merge = pd.merge(df_1, df_2, on='c')
In [21]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 3
1 2 5 4
2 4 2 3
a d c
0 3 5 1
1 1 1 4
2 2 6 3
Merge:
Out[21]:
a_x b c a_y d
0 1 2 3 2 6
1 4 2 3 2 6
2 2 5 4 1 1

Merge de dos dataframe por dos columnas

Para realizar un merge con dos columnas basta agregar en el argumento on una lista con los nombres de las columnas en común.
In [22]:
df_1 = pd.DataFrame([[1,2,5], [2,5,4],[4,2,3]], columns=['a', 'b', 'c'])
df_2 = pd.DataFrame([[3,5,1], [2,1,4],[2,6,3]], columns=['a', 'd', 'c'])
In [23]:
df_merge = pd.merge(df_1, df_2, on=['c', 'a'])
In [24]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 5
1 2 5 4
2 4 2 3
a d c
0 3 5 1
1 2 1 4
2 2 6 3
Merge:
Out[24]:
a b c d
0 2 5 4 1
Por defecto el merge utiliza el argumento how='inner' por lo que las filas que no tienen los elementos en común son expluídas, para mantener estas filas en el dataframe resultante se utiliza how='outer'. Los valores que no que no son comunes se mostrarán como NaN.
In [25]:
df_merge = pd.merge(df_1, df_2, on=['c', 'a'], how='outer')
In [26]:
display_inline(df_1, df_2)
print('Merge:')
df_merge
a b c
0 1 2 5
1 2 5 4
2 4 2 3
a d c
0 3 5 1
1 2 1 4
2 2 6 3
Merge:
Out[26]:
a b c d
0 1 2.0 5 NaN
1 2 5.0 4 1.0
2 4 2.0 3 NaN
3 3 NaN 1 5.0
4 2 NaN 3 6.0
Las filas completas se deben a que ciumplen la condición dada en el merge: El valor de la columna a y c sean iguales. Por ejemplo la fila 1 del dataframe df_mergeestá completa puesto que el valor 2 en a y el valor 4 en c está en los dos dataframe en la misma fila.
El valor de df_merge.loc[0, d] es NaN por que el valor 1 en a y el valor 5 en c no están en los dos dataframe en la misma fila, entonces se agrega la columna d sin un valor.

You Might Also Like

0 comments

Apoyado por: