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

Python中AnnData字典批量处理遇AttributeError问题求助

问题:批量处理AnnData字典时的报错与解决方法

背景与代码

作为Python新手(熟悉R列表),我用AnnData对象处理多样本数据,通过以下代码创建存储AnnData的字典:

for sample in samples:
    adata_atac_dict[sample] = sc.read_10x_mtx(
        os.path.join(
            _10xfilesPath + sample + "/filtered_feature_bc_matrix/"),
        var_names='gene_symbols',
        cache=True,
        gex_only=False)

为过滤特定特征类型,编写了如下函数:

def limit_features(atac_list:list)-> list:
    temp = atac_list.var['feature_types']
    return atac_list[:,temp=="Peaks"]

该函数单独处理字典中的单个样本(如adata_atac_dict['sample_A_1'])时能得到预期结果,但批量处理时出现问题。

报错情况

  1. 直接使用map处理字典:
atac_adata_list = list(map(limit_features, adata_atac_dict))

报错:

AttributeError: 'str' object has no attribute 'var'

  1. 使用values()后转字典:
adata_atac_dict2 = dict(map(limit_features, adata_atac_dict.values()))

报错:

ValueError: dictionary update sequence element #0 has length 1552; 2 is required

问题原因

  1. 第一个错误:Python中直接迭代字典时,默认遍历的是字典的键(字符串类型),而非对应的值(AnnData对象)。map把每个键传给limit_features,函数尝试访问字符串的var属性,自然报错。
  2. 第二个错误:map(limit_features, adata_atac_dict.values())返回的是一个个过滤后的AnnData对象,而dict()要求传入的是键值对组成的序列(每个元素是长度为2的元组/序列),直接传入AnnData对象不符合要求,因此报错。
  3. 额外问题:limit_features的类型注解错误——函数接收的是单个AnnData对象,不是列表,返回的也是AnnData对象,错误的类型注解会误导代码逻辑。

解决方案

1. 修正函数类型注解(必要步骤)

先把函数的类型提示修正为正确的AnnData类型:

import anndata

def limit_features(adata: anndata.AnnData) -> anndata.AnnData:
    temp = adata.var['feature_types']
    return adata[:, temp == "Peaks"]

2. 批量处理字典的正确方法

方法一:普通循环(直观易懂)

遍历字典的键值对,对每个AnnData对象应用过滤函数,同时保留原样本名称作为键:

adata_atac_dict_filtered = {}
for sample_name, adata in adata_atac_dict.items():
    adata_atac_dict_filtered[sample_name] = limit_features(adata)

方法二:字典推导式(简洁高效)

用Python的字典推导式一行完成,逻辑和循环一致:

adata_atac_dict_filtered = {name: limit_features(adata) for name, adata in adata_atac_dict.items()}

方法三:结合starmap使用map(保留键的前提下用map)

如果一定要用map类方法,需要同时处理键和值,返回键值对序列供dict()使用:

from itertools import starmap

def process_sample(name, adata):
    return name, limit_features(adata)

adata_atac_dict_filtered = dict(starmap(process_sample, adata_atac_dict.items()))

原理说明

  • 所有方法的核心都是直接遍历字典的键值对,确保limit_features接收的是AnnData对象而非字符串。
  • 字典推导式和starmap的方式本质上都是对键值对的批量处理,最终生成的新字典保留原有的样本名称与过滤后AnnData对象的映射关系,符合后续分析的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:46:12