Combinar dataframes usando pandas
julio 10, 2019
Creado: Julio 10 de 2019
Modificado: Julio 10 de 2019
Testeado en:
Modificado: Julio 10 de 2019
Testeado en:
- Python 3.6.4
- pandas 0.24.2
Descargar código: https://github.com/vilmauricio/pyciencia/tree/master/pandas
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]:
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]:
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]:
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
Out[8]:
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]:
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.
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_1
y 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
Out[12]:
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
Out[14]:
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
Out[16]:
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
Out[18]:
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
Out[21]:
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
Out[24]:
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
Out[26]:
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_merge
está 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.
0 comments