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

Pandas按范围合并区间:合并同染色体重叠/间接重叠区间并累加概率

合并Pandas中同一染色体的连通区间并求和概率

这是基因组数据分析里超常见的需求嘛,我来给你一步步拆解怎么高效实现:

首先,咱们先明确核心需求:同一染色体下,所有重叠或通过其他区间间接连通的区间要合并成一个大区间,同时把这些区间的probability求和。

第一步:构造示例数据

先拿一个贴近需求的示例DataFrame来演示,其中chr1的三个区间是间接连通的(10-20和18-28重叠,18-28又和25-35重叠,所以三个要合并成一个),chr2的两个区间直接重叠:

import pandas as pd

df = pd.DataFrame({
    'chrom': ['chr1', 'chr1', 'chr1', 'chr2', 'chr2'],
    'start': [10, 18, 25, 5, 15],
    'end': [20, 28, 35, 10, 20],
    'probability': [0.2, 0.3, 0.1, 0.4, 0.2]
})

第二步:定义区间合并函数

我们需要一个函数来处理单个染色体的区间,核心逻辑是先排序,再迭代合并连通区间,同时累加概率:

def merge_connected_intervals(group):
    # 先按start排序,确保区间按起始位置有序排列,这是合并连通区间的基础
    sorted_group = group.sort_values('start').reset_index(drop=True)
    if sorted_group.empty:
        return pd.DataFrame()
    
    # 初始化合并后的第一个区间
    merged_intervals = []
    current_start = sorted_group.iloc[0]['start']
    current_end = sorted_group.iloc[0]['end']
    current_prob = sorted_group.iloc[0]['probability']
    
    # 遍历后续每个区间
    for idx in range(1, len(sorted_group)):
        row = sorted_group.iloc[idx]
        # 判断当前区间是否和已合并的区间连通(这里默认是闭区间,若为左闭右开则改成row['start'] < current_end)
        if row['start'] <= current_end:
            # 合并区间:更新end为两者的最大值,累加概率
            current_end = max(current_end, row['end'])
            current_prob += row['probability']
        else:
            # 无连通,将已合并的区间存入列表,初始化新的区间
            merged_intervals.append({
                'chrom': sorted_group.iloc[0]['chrom'],
                'start': current_start,
                'end': current_end,
                'probability': current_prob
            })
            current_start = row['start']
            current_end = row['end']
            current_prob = row['probability']
    
    # 把最后一个合并的区间加入列表
    merged_intervals.append({
        'chrom': sorted_group.iloc[0]['chrom'],
        'start': current_start,
        'end': current_end,
        'probability': current_prob
    })
    
    return pd.DataFrame(merged_intervals)

第三步:分组应用合并函数

按chrom分组,把刚才的函数应用到每个组,最后合并结果:

final_merged_df = df.groupby('chrom').apply(merge_connected_intervals).reset_index(drop=True)

查看结果

运行后final_merged_df的输出如下:

chromstartendprobability
chr110350.6
chr25200.6

完全符合需求:chr1的三个连通区间合并成了10-35,概率求和为0.6;chr2的两个重叠区间合并成5-20,概率求和为0.6。

注意事项

  • 区间类型适配:如果你的区间是左闭右开(比如基因组常用的0-based坐标),记得把判断条件从row['start'] <= current_end改成row['start'] < current_end,避免错误合并不重叠的区间。
  • 缺失值处理:如果你的数据里有NaN值,建议先通过df.dropna(subset=['chrom', 'start', 'end', 'probability'])清理,避免函数出错。
  • 性能:这个方法的时间复杂度主要来自排序(O(n log n)),对于百万级别的区间数据也能高效处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:53:24