Pandas外连接合并DataFrame时如何保留原数据顺序(sort=False未生效)
Pandas外连接合并DataFrame时如何保留原数据顺序(sort=False未生效)
我完全懂你碰到的这个困扰——明明在merge里加了sort=False,但合并后的df3顺序还是和你想要的不一样。其实问题出在:sort=False只是告诉Pandas不要按连接键(这里是name)的字典序排序,但它并不会自动帮你保留df1的原始行顺序,再追加df2里独有的行。
要实现你想要的效果(先按df1的顺序保留所有行,再按df2的顺序追加df1里没有的行),可以在合并后手动指定排序规则,具体步骤如下:
解决方案代码
import pandas as pd data1 = [ ['4A', 1], ['3B', 2], ['2C', 3], ['1D', 4], ] data2 = [ ['2C', 9], ['4A', 3], ['6F', 2], ['5G', 1], ] df1 = pd.DataFrame(data1, columns=['name', 'value']) df2 = pd.DataFrame(data2, columns=['name', 'value']) # 先执行外连接合并 df3 = pd.merge(df1, df2, how='outer', on='name', sort=False) df3 = df3.rename({'value_x': 'v1', 'value_y': 'y2'}, axis=1) # 第一步:获取df1的name原始顺序 df1_name_order = df1['name'].tolist() # 第二步:筛选df2中独有的name,保留df2里的原始顺序 df2_unique_names = df2[~df2['name'].isin(df1_name_order)]['name'].tolist() # 第三步:组合成我们想要的完整顺序 target_order = df1_name_order + df2_unique_names # 第四步:按照目标顺序重新排序df3 df3 = df3.set_index('name').reindex(target_order).reset_index() print(df3)
输出结果
name v1 y2 0 4A 1.0 3.0 1 3B 2.0 NaN 2 2C 3.0 9.0 3 1D 4.0 NaN 4 6F NaN 2.0 5 5G NaN 1.0
原理说明
- 先提取
df1里name的原始顺序,确保合并后df1的行保持原来的排列; - 再筛选出
df2中独有的name,并且保留它们在df2里的出现顺序; - 最后用
reindex方法让df3按照我们组合好的顺序重新排列,完美匹配你的预期输出。
备注:内容来源于stack exchange,提问作者beetlej




