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

如何按递增染色体位置区间对DataFrame样本列分组求和及代码修正

基因组测序数据区间分组求和问题解决

问题背景

已有映射到基因组特定位点的DNA测序CSV数据,列定义:

  • 列0:染色体名称
  • 列1:核苷酸位置
  • 列2:标识字段
  • 列3-6:不同样本的序列映射次数

需求:按列1的**1-10000、10001-20000……**递增区间,分染色体、列2标识对样本列求和。

原尝试的pandas代码生成区间不符合预期,出现1-10000、10000-20000及错误大区间;用.loc[]循环处理多染色体区间时也遇到困难。

原代码:

MAX_SIZE = 10_000_000 # max chromosome size

bins = list(range(0, MAX_SIZE, 10_000))
bins[0] = 1
labels = [f'{a}-{b}' for a,b in zip(bins, bins[1:])]

group = pd.cut(data[1], bins, labels=labels).astype(str)

out = (data.groupby([0, group, 2])
       [[3, 4, 5]].sum().reset_index()
      )

问题原因

原代码的pd.cut默认采用左闭右开区间,手动修改bins[0]=1后,后续区间边界仍为10000、20000,导致第二个区间为[10000,20000),与第一个区间[1,10000)的边界重叠,标签文本和实际数值范围不匹配;同时超出MAX_SIZE的位置会被归到错误区间。

修正方案

方案一:数学计算生成区间标签(推荐)

直接通过整数运算定位区间,避免pd.cut的边界歧义:

BIN_SIZE = 10_000

# 计算每个核苷酸位置对应的区间起始值
data['interval'] = ((data[1] - 1) // BIN_SIZE) * BIN_SIZE + 1
# 生成符合要求的区间文本标签
data['interval'] = data['interval'].map(lambda x: f'{x}-{x + BIN_SIZE - 1}')

# 按染色体、区间、标识字段分组,对样本列求和
out = data.groupby([0, 'interval', 2])[[3, 4, 5, 6]].sum().reset_index()

核心逻辑:(位置-1)//BIN_SIZE得到区间索引,反推起始值后生成x到x+BIN_SIZE-1的连续区间,确保无重叠、无遗漏。

方案二:调整pd.cut参数适配需求

若偏好使用pd.cut,需重新生成bins并设置区间规则:

BIN_SIZE = 10_000
MAX_SIZE = 10_000_000

# 生成左边界序列:1, 10001, 20001...,最后补充MAX_SIZE+1确保覆盖所有位置
bins = list(range(1, MAX_SIZE + BIN_SIZE, BIN_SIZE))
if bins[-1] <= MAX_SIZE:
    bins.append(MAX_SIZE + 1)

# 生成对应区间标签
labels = [f'{a}-{a + BIN_SIZE - 1}' for a in bins[:-1]]

# 使用right=False设置左闭右开区间,匹配标签范围
group = pd.cut(data[1], bins=bins, labels=labels, right=False)

# 分组求和
out = data.groupby([0, group, 2])[[3, 4, 5, 6]].sum().reset_index()

这里的区间[1,10001)对应数值1-10000,[10001,20001)对应10001-20000,完美匹配需求标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:52:15