Mi pregunta está estrechamente relacionada con Pandas Merge: cómo evitar la duplicación de columnas pero no la misma.
Quiero concatenar las columnas que son diferentes en tres marcos de datos. Los marcos de datos tienen una identificación de columna y algunas columnas que son idénticas: Ej.
df1
id place name qty unit A 1 NY Tom 2 10 a 2 TK Ron 3 15 a 3 Lon Don 5 90 a 4 Hk Sam 4 49 a
df2
id place name qty unit B 1 NY Tom 2 10 b 2 TK Ron 3 15 b 3 Lon Don 5 90 b 4 Hk Sam 4 49 b
df3
id place name qty unit CD 1 NY Tom 2 10 cd 2 TK Ron 3 15 cd 3 Lon Don 5 90 cd 4 Hk Sam 4 49 cd
Resultado:
id place name qty unit ABCD 1 NY Tom 2 10 abcd 2 TK Ron 3 15 abcd 3 Lon Don 5 90 abcd 4 Hk Sam 4 49 abcd
El lugar, el nombre, la cantidad y la unidad de las columnas siempre formarán parte de los tres marcos de datos, los nombres de las columnas que son diferentes podrían variar (A, B, C, D en mi ejemplo). Los tres marcos de datos tienen el mismo número de filas.
Yo he tratado:
cols_to_use = df1.columns - df2.columns dfNew = merge(df, df2[cols_to_use], left_index=True, right_index=True, how='outer')
El problema es que obtengo más filas de las esperadas y el cambio de nombre de las columnas en el dataframe resultante (cuando se usa concat).
Usando reduce
desde functools
from functools import reduce reduce(lambda left,right: pd.merge(left,right), [df1,df2,df3]) Out[725]: id place name qty unit ABCD 0 1 NY Tom 2 10 abcd 1 2 TK Ron 3 15 abcd 2 3 Lon Don 5 90 abcd 3 4 Hk Sam 4 49 abcd
Puede utilizar la combinación anidada
merge_on = ['id','place','name','qty','unit'] df1.merge(df2, on = merge_on).merge(df3, on = merge_on) id place name qty unit ABCD 0 1 NY Tom 2 10 abcd 1 2 TK Ron 3 15 abcd 2 3 Lon Don 5 90 abcd 3 4 Hk Sam 4 49 abcd
Usando concat
con groupby
y first
:
pd.concat([df1, df2, df3], 1).groupby(level=0, axis=1).first()
ABCD id name place qty unit 0 abcd 1 Tom NY 2 10 1 abcd 2 Ron TK 3 15 2 abcd 3 Don Lon 5 90 3 abcd 4 Sam Hk 4 49
Puede extraer solo las columnas de df2
(y df3
manera similar) que no están ya presentes en df1
. Luego simplemente use pd.concat
para concatenar los marcos de datos:
cols = [c for c in df2.columns if c not in df1.columns] df = pd.concat([df1, df2[cols]], axis=1)