You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并存在重叠项的两个DataFrame并保留原始顺序

问题描述

现有两个包含区域名称的DataFrame,其中area1_name和area2_name存在重叠项,需要将两个区域名称合并为一个长列表,并按指定顺序排列。

原始数据:

import pandas as pd

df1 = pd.DataFrame({'area1_index': [0,1,2,3,4,5], 'area1_name': ['AL','AK','AZ','AR','CA','CO']})

df2 = pd.DataFrame({'area2_index': [0,1,2,3,4,5,6], 'area2_name': ['MN','AL','CT','TX','AK','AR','CA']})

期望得到的最终结果:

final = pd.DataFrame({'area1_index': [pd.NA,0,pd.NA,pd.NA,1,2,3,4,5], 
                      'area1_name': [pd.NA,'AL',pd.NA,pd.NA,'AK','AZ','AR','CA','CO'], 
                      'area2_index': [0,1,2,3,4,pd.NA,5,6,pd.NA], 
                      'area2_name':['MN','AL','CT','TX','AK',pd.NA,'AR','CA',pd.NA]})

尝试手动识别重叠区域和缺失部分再合并,但合并后会自动按索引排序,无法得到期望的顺序:

df1_df2_overlap = pd.DataFrame({'area1_index': [0,1,3,4], 'area2_index': [1,4,5,6], 'area1_name': ['AL','AK','AR','CA']})
df2_missing = pd.DataFrame({'area2_index': [0,2,3], 'area2_name': ['MN','CT','TX']})

df3 = pd.merge(df1, df2, "outer")
df4 = pd.merge(df3, df2_missing, "outer")
解决方案

方法一:合并后按自定义映射排序(无需手动拆分)

不需要提前识别重叠/缺失部分,先通过外连接合并数据,再为每个区域名称指定排序优先级即可:

  1. 外连接合并两个DataFrame,以区域名称为连接键:
merged = pd.merge(df1, df2, left_on='area1_name', right_on='area2_name', how='outer')
  1. 定义目标排序顺序,生成排序映射字典:
# 排序规则:df2独有项 → 重叠项(按df1顺序) → df1独有项
order = ['MN', 'AL', 'CT', 'TX', 'AK', 'AZ', 'AR', 'CA', 'CO']
sort_mapping = {name: idx for idx, name in enumerate(order)}
  1. 添加临时排序列,按该列排序后整理格式:
# 统一提取区域名称用于排序
merged['sort_key'] = merged['area1_name'].fillna(merged['area2_name']).map(sort_mapping)
# 排序并重置索引
result = merged.sort_values('sort_key').reset_index(drop=True)
# 调整列顺序为期望格式
result = result[['area1_index', 'area1_name', 'area2_index', 'area2_name']]

方法二:分块拼接(贴合原始逻辑)

如果想保留拆分重叠/缺失的思路,可按目标顺序拼接各部分:

  1. 提取各部分数据:
# df2独有的区域
df2_unique = df2[~df2['area2_name'].isin(df1['area1_name'])]
# 重叠区域(按df1的顺序排序)
overlap = pd.merge(df1, df2, left_on='area1_name', right_on='area2_name')
overlap = overlap.set_index('area1_name').loc[df1['area1_name'][df1['area1_name'].isin(df2['area2_name'])]].reset_index()
# df1独有的区域
df1_unique = df1[~df1['area1_name'].isin(df2['area2_name'])]
  1. 按顺序拼接并整理格式:
# 统一临时列名方便拼接
df2_unique = df2_unique.rename(columns={'area2_name': 'name'})
overlap = overlap.rename(columns={'area1_name': 'name'})
df1_unique = df1_unique.rename(columns={'area1_name': 'name'})

# 按目标顺序拼接
combined = pd.concat([df2_unique, overlap, df1_unique], ignore_index=True)
# 恢复原始列名并填充缺失值
result = combined.assign(
    area1_name=combined['name'].where(combined['area1_index'].notna(), pd.NA),
    area2_name=combined['name'].where(combined['area2_index'].notna(), pd.NA)
).drop('name', axis=1)[['area1_index', 'area1_name', 'area2_index', 'area2_name']]

内容的提问来源于stack exchange,提问作者Jen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:07:24