Concatene columnas distintas en dos marcos de datos utilizando pandas (y agregue columnas similares)

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)