pandas concat横向拼接多个DataFrame时同名列未合并如何解决
pandas按索引拼接时同名列自动合并方案
问题复现
首先构造测试用的三个DataFrame:
import pandas as pd df1 = pd.DataFrame({'a':['id1','id2','id3'],'b':['W','W','W'],'c1':[1,2,3]}) df2 = pd.DataFrame({'a':['id1','id2','id3'],'b':['W','W','W'],'c2':[4,5,6]}) df3 = pd.DataFrame({'a':['id1','id4','id5'],'b':['Q','Q','Q'],'c1':[7,8,9]})
预期拼接结果如下:
a b c1 c2 0 id1 W 1 4.0 1 id2 W 2 5.0 2 id3 W 3 6.0 3 id1 Q 7 NaN 4 id4 Q 8 NaN 5 id5 Q 9 NaN
原有实现先将三个表设置['a','b']为索引后做横向拼接:
l = [d.set_index(['a','b']) for d in [df1,df2,df3]] pd.concat(l, axis=1)
运行后pandas不会自动合并重名的c1列,会生成两列独立的c1,不符合预期:
c1 c2 c1 a b id1 W 1.0 4.0 NaN id2 W 2.0 5.0 NaN id3 W 3.0 6.0 NaN id1 Q NaN NaN 7.0 id4 Q NaN NaN 8.0 id5 Q NaN NaN 9.0
正确实现
pandas横向拼接遇到重名列时默认会保留所有同名列,不会自动做值合并,两种简单调整方式可以实现预期效果:
方式1:纵向拼接后按索引聚合
直接纵向拼接所有表,相同列名会自动对齐,缺失值自动填充为NaN,再按a、b列分组取非空值即可:
result = pd.concat([df1, df2, df3], ignore_index=True)\ .groupby(['a','b'], as_index=False).first()
逻辑很简单:纵向拼接后,同一组(a,b)的不同字段值会分散在不同行,每组每个字段只会有一个非空值,取第一个非空值就能把同组数据合并到同一行。
方式2:横向拼接后按列名聚合
如果要保留横向拼接的逻辑,可以在拼接完成后,按列名分组聚合,把同名列的非空值合并到一列:
l = [d.set_index(['a','b']) for d in [df1,df2,df3]] concat_res = pd.concat(l, axis=1) result = concat_res.groupby(level=0, axis=1).first().reset_index()
两种方式运行后输出完全匹配预期结果。
提示:如果同一
(a,b)组合在多个来源表的同一个字段都有值,上述写法会优先保留先传入的DataFrame中的值,适配当前场景需求。
内容的提问来源于stack exchange,提问作者HappyPy
相关产品推荐
相关产品推荐

