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

为clr_A0.chromnames元素添加chr前缀时触发AttributeError问题

解决cooler库中chromnames无法直接赋值的AttributeError问题

问题背景

需要给clr_A0.chromnames的所有元素添加chr前缀,原代码尝试直接赋值但触发AttributeError: can't set attribute。

原代码

import cooler
import cooltools.lib.plotting
import cooltools
from pathlib import Path


pathlist = Path(data_dir).glob('**/*.mcool')
for path in pathlist:
     
     cool_file = str(path)
     filename = cool_file.split("/",1)[1]    
     resolution = [i.rsplit("/", 1)[1] for i in cooler.fileops.list_coolers(cool_file)]
         
     ### load a cooler for each resolution 
     for j in resolution:
            if filename.startswith("A0"):
                clr_A0 = cooler.Cooler(f'{cool_file}::resolutions/{j}')
                clr_A0.chromnames = ["chr" + s for s in clr_A0.chromnames]

报错信息

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [37], in <cell line: 2>()
     10 if filename.startswith("A0"):
     11     clr_A0 = cooler.Cooler(f'{cool_file}::resolutions/{j}')
---> 12     clr_A0.chromnames = ["chr" + s for s in clr_A0.chromnames]

AttributeError: can't set attribute

输入的clr_A0.chromnames

['M',
 '1',
 '2',
 '3',
 '4',
 '5',
 '6',
 '7',
 '8',
 '9',
 '10',
 '11',
 '12',
 '13',
 '14',
 '15',
 '16',
 '17',
 '18',
 '19',
 '20',
 '21',
 '22',
 'X',
 'Y']

期望输出

['chrM',
 'chr1',
 'chr2',
 'chr3',
 'chr4',
 'chr5',
 'chr6',
 'chr7',
 'chr8',
 'chr9',
 'chr10',
 'chr11',
 'chr12',
 'chr13',
 'chr14',
 'chr15',
 'chr16',
 'chr17',
 'chr18',
 'chr19',
 'chr20',
 'chr21',
 'chr22',
 'chrX',
 'chrY']

原因分析

cooler.Cooler对象的chromnames是只读属性,无法直接赋值修改。它是从底层HDF5文件中读取的元数据,直接修改会破坏数据一致性,因此被设计为不可写。

解决方法

方案1:创建新Cooler对象并保存

复制原Cooler的所有数据,替换染色体名称后写入新文件,不修改原数据:

import cooler
import cooltools.lib.plotting
import cooltools
from pathlib import Path

pathlist = Path(data_dir).glob('**/*.mcool')
for path in pathlist:
    cool_file = str(path)
    filename = cool_file.split("/",1)[1]    
    resolution = [i.rsplit("/", 1)[1] for i in cooler.fileops.list_coolers(cool_file)]
    
    for j in resolution:
        if filename.startswith("A0"):
            clr_A0 = cooler.Cooler(f'{cool_file}::resolutions/{j}')
            # 生成带chr前缀的新染色体名称
            new_chroms = [f"chr{s}" for s in clr_A0.chromnames]
            # 复制bins表并替换染色体名称
            new_bins = clr_A0.bins()[:].assign(chrom=new_chroms)
            # 创建新的Cooler对象并保存
            new_cool_path = f'{cool_file}_chr_prefix::resolutions/{j}'
            cooler.Cooler.create(
                new_cool_path,
                clr_A0.matrix(balance=False),
                bins=new_bins,
                metadata=clr_A0.metadata
            )

方案2:直接修改原文件的bins表(需谨慎)

如果需要直接修改原文件,可通过可写模式打开Cooler,修改底层bins表的染色体名称:

import cooler
import cooltools.lib.plotting
import cooltools
from pathlib import Path

pathlist = Path(data_dir).glob('**/*.mcool')
for path in pathlist:
    cool_file = str(path)
    filename = cool_file.split("/",1)[1]    
    resolution = [i.rsplit("/", 1)[1] for i in cooler.fileops.list_coolers(cool_file)]
    
    for j in resolution:
        if filename.startswith("A0"):
            # 以可写模式打开cooler文件
            with cooler.Cooler(f'{cool_file}::resolutions/{j}', mode='r+') as clr_A0:
                # 读取bins表并修改染色体名称
                bins = clr_A0.bins()[:]
                bins['chrom'] = bins['chrom'].apply(lambda x: f"chr{x}")
                # 将修改后的bins表写回文件
                clr_A0.bins()[:] = bins

注意:方案2会直接修改原文件,操作前务必备份数据,避免不可逆的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:20:34