Tengo una lista de marcos de datos de pandas como se muestra a continuación y me gustaría combinarlos/fusionarlos para que los valores en la columna compartida sean exhaustivos entre todos los marcos de datos. ¿Cuál es el mejor enfoque?
DF 1:
| Col1 | Col2 |
|---|---|
| BLAH1 | UN |
| BLAH2 | Z |
DF 2:
| Col1 | Col2 | Col3 |
|---|---|---|
| BLAH2 | Z | B |
| BLAH3 | q | k |
DF 3:
| Col1 | Col4 |
|---|---|
| BLAH2 | C |
| BLAH3 | W |
Resultado deseado
| Col1 | Col2 | Col3 | Col4 |
|---|---|---|---|
| BLAH1 | UN | Yaya | Yaya |
| BLAH2 | Z | B | C |
| BLAH3 | q | k | W |
Si las claves son únicas, dentro de cada marco de datos, puede hacer un concat y luego agrupar por:
list_dfs = [df1, df2, df3] pd.concat(list_dfs).groupby('Col1').first() En general, puede combinar reduce y merge :
from functools import reduce # find common columns commons = reduce(lambda x,y: set(x).intersection(set(y)), list_dfs) reduce(lambda x,y: x.merge(y, on=commons), list_dfs)Podemos usar reduce y merge así:
from functools import reduce reduce(lambda left, right: pd.merge(left, right, on=list(left.columns.intersection(right.columns)), how='outer'), [df1, df2, df3]) Aquí, la función reduce aplica la función de dos argumentos de forma acumulativa a los elementos de iterable, de izquierda a derecha, para reducir el iterable a un solo valor.
El argumento de la izquierda, left , es el valor acumulado y el argumento de la derecha, right , es el valor de actualización del iterable.
El truco aquí es merge la lista de columnas comunes de DataFrames para obtener el resultado esperado. @QuangHoang hizo algo similar y encontró el truco antes que yo.
Producción :
Col1 Col2 Col3 Col4 0 BLAH1 A NaN NaN 1 BLAH2 ZBC 2 BLAH3 QKWfunctools.reduce con pd.DataFrame.combine_first y comprensión:
from functools import reduce reduce(lambda x, y: x.combine_first(y), (df.set_index('Col1') for df in [df1,df2,df3])).reset_index()Producción:
Col1 Col2 Col3 Col4 0 BLAH1 A NaN NaN 1 BLAH2 ZBC 2 BLAH3 QKWDados los marcos de datos de entrada como:
df1 = pd.DataFrame({'Col1':['BLAH1', 'BLAH2'], 'Col2':[*'AZ']}) df2 = pd.DataFrame({'Col1':['BLAH2', 'BLAH3'], 'Col2':[*'ZQ'], 'Col3':[*'BK']}) df3 = pd.DataFrame({'Col1':['BLAH2', 'BLAH3'], 'Col4':[*'CW']})