如何按顺序合并多个DataFrame?现有尝试未达预期求正确方法
问题描述
我原以为这个问题应该有重复提问,但没找到合适答案。按顺序合并多个DataFrame时遇到问题,现有四个DataFrame如下:
df1 = pd.DataFrame({'source': ['A', 'A', 'A', 'B', 'B', 'C', 'C'], 'target': ['1', '2', '3', '4', '5', '6', '7']}) df2 = pd.DataFrame({'source': ['A', 'A'], 'temp': ['a', 'b']}) df3 = pd.DataFrame({'source': ['B', 'B'], 'temp': ['c', 'd']}) df4 = pd.DataFrame({'source': ['C'], 'temp': ['e']})
期望合并后得到如下结果:
# source target temp #0 A 1 a #1 A 1 b #2 A 2 a #3 A 2 b #4 A 3 a #5 A 3 b #6 B 4 c #7 B 4 d #8 B 5 c #9 B 5 d #10 C 6 e #11 C 7 e
我试了三种代码,都没得到预期结果:
#Trial 1 dfs = pd.merge(df1, df2, on='source', how='left') dfs = pd.merge(dfs, df3, on='source', how='left') # 生成了带前缀的新列,但我只想保留source、target、temp三列 #Trial 2 dfs = pd.merge(df1, df2, on='source', how='left') dfs['temp']=dfs.set_index('source')['temp'].fillna(df3.set_index('source')['temp'].to_dict()).values # 只能填充固定数量的NaN,但实际情况是一个NaN对应其他df里的多个值,这样处理有问题 #Trial 3 dfs = pd.merge(df1, df2, on='source', how='left') dfs[dfs['source']=='B']['temp']=pd.merge(df1, df3, on='source', how='left')['temp'].dropna() # 根本没修改dfs
解决方案
步骤1:合并所有temp映射表
先把df2、df3、df4纵向拼接,得到每个source对应的全部temp值:
temp_df = pd.concat([df2, df3, df4], ignore_index=True)
步骤2:与df1做笛卡尔积合并
通过pd.merge按source关联,默认的内连接会自动将每个target与对应source下的所有temp配对,生成期望的结果:
result = pd.merge(df1, temp_df, on='source')
最终结果
运行后result的输出如下,完全符合预期:
source target temp 0 A 1 a 1 A 1 b 2 A 2 a 3 A 2 b 4 A 3 a 5 A 3 b 6 B 4 c 7 B 4 d 8 B 5 c 9 B 5 d 10 C 6 e 11 C 7 e
之前尝试失败的原因
- Trial1:连续merge时,重复列名会被添加前缀区分,且这种方式无法实现一对多的笛卡尔积配对,不符合需求。
- Trial2:
fillna仅支持单个值填充NaN,无法处理一个source对应多个temp的场景,只能填充单一值而非所有可能的temp。 - Trial3:
dfs[dfs['source']=='B']属于链式索引,返回的是原DataFrame的临时切片,赋值操作不会作用到原DataFrame上,因此没有修改效果。
内容的提问来源于stack exchange,提问作者Ssong
相关产品推荐
相关产品推荐

