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

DNA坐标非重叠区间提取咨询:同染色体外显子数据处理

提取DNA非重叠区间解决方案

问题描述

需要处理基因组区间数据,针对同一染色体、同一外显子的多行记录,提取外显子区间中完全不与任何start1-end1区间重叠的区域,最终生成non_overlap列(理想状态可拆分为non_overlap_start和non_overlap_end列)。

初始数据示例

import pandas as pd

df = pd.DataFrame({
    'chrom': [1,1,1,2],
    'exon_start': [1,1,150,5],
    'exon_end': [100,100,155,50],
    'start1': [50,70,155,25],
    'end1': [60,80,160,100]
})

解决方案步骤

核心思路是按染色体+外显子分组,合并组内所有重叠的start1-end1区间,再计算外显子区间与合并后区间的差集:

  1. 定义区间处理函数:负责截断超出外显子的区间、合并重叠区间、计算非重叠区域
  2. 分组应用函数:对每个染色体-外显子组计算非重叠区域
  3. 可选:拆分区间列:将non_overlap的字符串列表拆分为起始/终止列

代码实现

def get_non_overlap(exon_start, exon_end, intervals):
    # 截断每个start1-end1区间到外显子范围内
    trimmed_intervals = []
    for s, e in intervals:
        trim_s = max(s, exon_start)
        trim_e = min(e, exon_end)
        if trim_s <= trim_e:
            trimmed_intervals.append((trim_s, trim_e))
    
    # 合并重叠/相邻的区间
    if not trimmed_intervals:
        return [(exon_start, exon_end)]
    # 按起始坐标排序
    sorted_intervals = sorted(trimmed_intervals, key=lambda x: x[0])
    merged = [list(sorted_intervals[0])]
    for s, e in sorted_intervals[1:]:
        last_s, last_e = merged[-1]
        if s <= last_e + 1:  # 相邻区间也合并
            merged[-1][1] = max(last_e, e)
        else:
            merged.append([s, e])
    
    # 计算外显子与合并后区间的差集
    non_overlap_regions = []
    prev_end = exon_start
    for s, e in merged:
        if prev_end < s:
            non_overlap_regions.append((prev_end, s - 1))
        prev_end = max(prev_end, e)
    if prev_end < exon_end:
        non_overlap_regions.append((prev_end + 1, exon_end))
    
    # 格式化为字符串格式
    return [f"{a}-{b}" for a, b in non_overlap_regions]

# 按染色体、外显子起始/终止分组,收集每组的所有start1-end1区间
grouped_intervals = df.groupby(['chrom', 'exon_start', 'exon_end'])[['start1', 'end1']].apply(
    lambda x: list(zip(x['start1'], x['end1']))
).rename('intervals')

# 合并分组结果到原DataFrame
df = df.merge(grouped_intervals, on=['chrom', 'exon_start', 'exon_end'])

# 计算non_overlap列
df['non_overlap'] = df.apply(
    lambda row: get_non_overlap(row['exon_start'], row['exon_end'], row['intervals']),
    axis=1
)

# 可选:拆分non_overlap为起始/终止列(需展开多行)
df_exploded = df.explode('non_overlap')
df_exploded[['non_overlap_start', 'non_overlap_end']] = df_exploded['non_overlap'].str.split('-', expand=True).astype(int)

# 清理临时列
df = df.drop('intervals', axis=1)

最终结果

处理后的DataFrame:

chrom  exon_start  exon_end  start1  end1                  non_overlap
0      1           1       100      50    60  [1-49, 61-69, 81-100]
1      1           1       100      70    80  [1-49, 61-69, 81-100]
2      1         150       155     155   160                [150-154]
3      2           5        50      25   100                  [5-24]

关键说明

  • 分组逻辑:必须以chrom+exon_start+exon_end作为分组键,确保只处理同一外显子下的所有目标区间
  • 区间截断:避免start1-end1超出外显子范围的部分干扰非重叠区域计算
  • 区间合并:减少差集计算的复杂度,确保只处理连续的覆盖区域

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:13:21