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

如何在Python中合并存在From/To区间重叠的两个数据集?

解决同ID下区间重叠的数据集合并问题

核心思路

把每个ID对应的所有区间(df1+df2)的起止点提取出来,拆分成无重叠的细小区间,再逐个判断每个细小区间属于「仅df1覆盖」「仅df2覆盖」「两者重叠覆盖」,对应取数:重叠和仅df2的用df2数据,仅df1的用df1数据。

具体实现步骤(基于Pandas)

先假设你的数据集结构示例如下:

import pandas as pd

# 示例数据
df1 = pd.DataFrame({
    'ID': ['A', 'A'],
    'From': [1, 10],
    'To': [8, 20],
    'Var1': ['df1_1', 'df1_2'],
    'Var2': ['v1', 'v2']
})

df2 = pd.DataFrame({
    'ID': ['A', 'A'],
    'From': [5, 15],
    'To': [12, 18],
    'Var1': ['df2_1', 'df2_2'],
    'Var3': ['v3', 'v4']  # df2独有的额外变量
})

1. 定义单ID区间处理函数

针对单个ID的子数据集,生成拆分后的细小区间并匹配对应数据:

def process_id_group(id_df1, id_df2):
    # 提取所有区间的起止点,去重后排序
    all_points = sorted(set(id_df1[['From', 'To']].values.flatten().tolist() + 
                           id_df2[['From', 'To']].values.flatten().tolist()))
    # 生成无重叠的细小区间
    intervals = []
    for i in range(len(all_points)-1):
        start = all_points[i]
        end = all_points[i+1]
        if start == end:
            continue  # 跳过空区间
        intervals.append((start, end))
    
    result_rows = []
    # 遍历每个细小区间,匹配数据源
    for start, end in intervals:
        # 判断该区间是否被df1覆盖
        df1_match = (id_df1['From'] <= start) & (id_df1['To'] >= end)
        # 判断该区间是否被df2覆盖
        df2_match = (id_df2['From'] <= start) & (id_df2['To'] >= end)
        
        if df2_match.any():
            # 取df2中覆盖该区间的行,替换起止点为当前细小区间
            row = id_df2[df2_match].iloc[0].copy()
            row['From'] = start
            row['To'] = end
            result_rows.append(row)
        elif df1_match.any():
            # 取df1中覆盖该区间的行,替换起止点为当前细小区间
            row = id_df1[df1_match].iloc[0].copy()
            row['From'] = start
            row['To'] = end
            result_rows.append(row)
    
    return pd.DataFrame(result_rows)

2. 按ID批量处理并合并结果

# 遍历所有唯一ID,逐个处理后合并
unique_ids = df1['ID'].unique()
final_result = pd.DataFrame()

for id_val in unique_ids:
    df1_sub = df1[df1['ID'] == id_val].reset_index(drop=True)
    df2_sub = df2[df2['ID'] == id_val].reset_index(drop=True)
    processed_data = process_id_group(df1_sub, df2_sub)
    final_result = pd.concat([final_result, processed_data], ignore_index=True)

# 重置索引(可选)
final_result = final_result.reset_index(drop=True)

结果说明

  • 拆分后的区间会自动处理重叠部分,重叠区域直接使用df2的行数据(包括其额外变量)
  • df1独有的区间保留原df1数据
  • 同名变量(比如示例中的Var1)会自动取df2的值,因为直接复用了df2的行记录

注意事项

  • 如果一个细小区间被df1或df2的多行覆盖,当前逻辑默认取第一行,你可以根据实际需求调整(比如取最新行、合并多行列值等)
  • 确保From和To是数值/日期时间类型,日期类型的处理逻辑和数值完全一致,仅需保证数据格式为datetime64即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 10:48:19