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

如何用Pandas为无覆盖度的bins填充0以生成完整热图

为无覆盖的基因组Bin填充0以完整显示热图

需求与问题

需要按固定数量的Bin计算每个Bin内位点的平均覆盖度,用于生成热图(不考虑每个Bin的碱基数)。但当前处理逻辑会自动隐藏无覆盖的Bin,导致热图中缺失对应区间,需要将这些无覆盖Bin的平均覆盖度设为0,确保它们在热图中正常显示。

输入数据示例

chr17   1   1
chr17   5   1
chr17   5   2
chr17   5   2
chr17   7   1
chr17   7   5
chr17   10  1

当前输出问题

处理后缺失了无覆盖的Bin(如示例中的(2,4]):

chr                data_bin        avg
  chr17                   (0,2]          1
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (6,8]          3
  chr17                   (6,8]          3
  chr17                  (8,10]          1

期望输出

补全无覆盖的Bin并将其avg设为0:

chr                data_bin        avg
  chr17                   (0,2]          1
  chr17                   (2,4]          0
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (4,6]       1.66
  chr17                   (6,8]          3
  chr17                   (6,8]          3
  chr17                  (8,10]          1

当前使用的函数

def bins_calculator(path_txt:str, start:int,end:int):
    column_names =["chr", "pos", "cov"]
    data = pd.read_csv(path_txt, names = column_names, sep = '\t')
    step = int((end - start) / 10)
    n_bins = [start + i * step for i in range(11)]
    n_bins[-1] = end
    data["data_bin"] = pd.cut(data["pos"], bins = n_bins)
    data["avg"] = data.groupby("data_bin", observed = False)["cov"].transform("mean")
    filtered_data = data[["chr","data_bin","avg"]].drop_duplicates("data_bin")
    return filtered_data

解决方案

核心是先构造所有预设的Bin区间,再通过左连接补全缺失的Bin并填充0。修改后的函数如下:

def bins_calculator(path_txt:str, start:int, end:int):
    column_names = ["chr", "pos", "cov"]
    data = pd.read_csv(path_txt, names=column_names, sep='\t')
    
    # 生成10个固定Bin的区间
    step = int((end - start) / 10)
    n_bins = [start + i * step for i in range(11)]
    n_bins[-1] = end
    # 获取所有完整的Bin区间对象
    all_bins = pd.cut(pd.Series(n_bins), bins=n_bins).drop_duplicates().dropna()
    
    # 计算每个染色体-Bin组合的平均覆盖度
    data["data_bin"] = pd.cut(data["pos"], bins=n_bins)
    avg_by_bin = data.groupby(["chr", "data_bin"], observed=False)["cov"].mean().reset_index()
    
    # 生成所有染色体与所有Bin的完整组合
    unique_chrs = data["chr"].unique()
    full_bins = pd.MultiIndex.from_product([unique_chrs, all_bins], names=["chr", "data_bin"]).to_frame(index=False)
    
    # 左连接补全缺失的Bin,并用0填充无覆盖的avg值
    result = full_bins.merge(avg_by_bin, on=["chr", "data_bin"], how="left")
    result["avg"] = result["avg"].fillna(0)
    
    # 还原为原数据的行数格式(每个位点对应所属Bin的avg)
    final_data = data[["chr", "pos", "data_bin"]].merge(result, on=["chr", "data_bin"], how="left")
    final_data = final_data[["chr", "data_bin", "avg"]]
    
    return final_data

关键步骤说明

  1. 构造完整Bin集合:通过pd.cut生成所有预设的Bin区间,确保没有遗漏。
  2. 分组计算平均覆盖度:按染色体和Bin分组,计算每个组合的平均覆盖度。
  3. 补全缺失组合:用笛卡尔积生成所有染色体与Bin的完整组合,再通过左连接将已有数据匹配进去。
  4. 填充0值:对缺失的平均覆盖度用0填充,保证无覆盖Bin的数值存在。
  5. 还原格式:将结果与原数据合并,回到每个位点对应所属Bin平均覆盖度的格式,满足后续热图绘制需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:44:55