Pandas Outer Merge后右表非匹配行被置底,如何调整为目标排序?
实现自定义顺序的Outer Join结果排列
要实现你想要的穿插排列效果,核心是利用原DataFrame的行位置信息,给不同类型的行设置排序权重,让右表不匹配的行插入到左表对应位置的后面。具体步骤如下:
- 给原表添加原始索引列:分别给左表和右表新增一列记录它们的原始行位置,用来后续确定插入顺序。
- 执行Outer Join:保留原始索引列一起合并。
- 构造排序键:给左表相关的行(匹配行+左表独有行)设置整数排序键(等于左表原始索引),给右表独有的行设置小数排序键(等于右表原始索引 + 0.5),这样右表不匹配行就会排在左表对应位置行的后面。
- 按排序键排序并清理:排序后删除辅助的索引列,得到目标结果。
代码示例
import pandas as pd # 左表数据 one_final_df = pd.DataFrame({ 'A_1': [23, 1100, 450, 350], 'B_1': [54, 1300, 600, 560] }) # 右表数据 two_final_df = pd.DataFrame({ 'A_2': [1200, 1100, 500, 350], 'B_2': [1400, 1300, 600, 560] }) # 给原表添加原始索引列 one_final_df['left_idx'] = one_final_df.index two_final_df['right_idx'] = two_final_df.index # 执行outer join并保留索引列 final_df = pd.merge( one_final_df, two_final_df, left_on=['A_1', 'B_1'], right_on=['A_2', 'B_2'], how='outer' ) # 构造排序键:左表相关行用整数索引,右表独有行用索引+0.5实现插入 final_df['sort_key'] = final_df.apply( lambda row: row['left_idx'] if pd.notna(row['left_idx']) else row['right_idx'] + 0.5, axis=1 ) # 排序并清理辅助列 final_df = final_df.sort_values('sort_key').drop(columns=['left_idx', 'right_idx', 'sort_key']) # 重置索引(按需选择) final_df = final_df.reset_index(drop=True) print(final_df)
输出结果
A_1 B_1 A_2 B_2 0 23.0 54.0 NaN NaN 1 NaN NaN 1200.0 1400.0 2 1100.0 1300.0 1100.0 1300.0 3 450.0 600.0 NaN NaN 4 NaN NaN 500.0 600.0 5 350.0 560.0 350.0 560.0
关键说明
- 给右表独有行设置
right_idx + 0.5的排序键,是为了让它刚好排在左表对应索引行的后面(比如右表索引0的行,排序键是0.5,会排在左表索引0的行(排序键0)之后,左表索引1的行(排序键1)之前)。 - 如果你的原表使用的不是默认整数索引,只需要手动生成一个从0开始的位置序列列替换
index即可。
内容的提问来源于stack exchange,提问作者iamcyruss
相关产品推荐
相关产品推荐

