需要多久
创建于:2025年2月22日
创建于:2025年2月22日
需要多久
这几行代码(regress_out
与 scale
)的运行时间主要取决于以下因素:
一般来说,在几千到几万个细胞、几千到上万个基因的典型规模下:
sc.pp.regress_out
有时需要 几秒到几分钟 不等,取决于回归时需要做的线性回归模型数量(通常每个基因都要回归一次)。sc.pp.scale
通常速度较快,通常在秒级到十几秒左右就能完成。如果你的数据集非常庞大(数十万细胞、数万基因),或者硬件性能一般,耗时会更长,可能在数分钟到数十分钟不等。建议在实际环境中先用 Jupyter 的魔法命令(如 %%time
) 或者 Python 的 time
等方法做一下小范围测试,看一下具体的运行时间,之后再根据需要做进一步优化(如裁剪数据或并行计算)。
SCVI 模型
scVI(Single-cell Variational Inference) 是一种基于深度生成模型(变分自编码器,VAE)的单细胞测序数据分析框架。它能够同时完成数据的去噪、整合、批次效应校正等任务,还能输出细胞在低维潜在空间中的表示(embedding),在许多单细胞 RNA-seq 分析流程中使用非常广泛。
下面从原理、常见流程和时间消耗三个方面简要介绍一下。
深度生成模型
scVI 利用变分自编码器(Variational Autoencoder, VAE)对单细胞转录组表达矩阵进行建模。VAE 通过学习一个低维潜在表示(latent representation),在保留主要生物学变化信息的同时,能够降低噪音并去除批次效应。
批次效应校正
对于来自不同实验批次或不同测序平台的单细胞数据,scVI 会将这些批次信息(batch)作为模型的一个可选输入变量,以帮助在潜在空间中校正批次差异并获得更可比的表达模式。
基因表达分布假设
在模型中,基因表达通常被视为负二项分布(Negative Binomial)或零膨胀负二项分布(ZINB)。scVI 通过神经网络来学习这些分布的参数,从而更好地拟合单细胞数据的离散性和稀疏性。
以 scvi-tools(官方 Python 包)为例,常见流程如下:
pythonimport scvi # 1. 准备 AnnData 对象 # 假设变量名是 adata,含有单细胞测序数据 # 同时 adata.obs 中需要有 batch 信息(可选) # 2. 注册并设置 scVI 模型所需的参数 scvi.model.SCVI.setup_anndata( adata, batch_key="batch", # 如果有批次信息,可以指定列名 layer="counts", # 如果你的表达矩阵在某个 layer # 其他可选参数,如 labels_key 等 ) # 3. 初始化模型 model = scvi.model.SCVI( adata, n_latent=10, # 潜在空间维度,可根据需要调整 gene_likelihood='zinb', # 常见的选择,有 'zinb' 或 'nb' # 其他超参数 ... ) # 4. 训练模型 model.train( max_epochs=400, # 训练轮数,可根据数据大小和效果调节 use_gpu=True # 如果有 GPU,可以开启加速 ) # 5. 获取结果 # - 提取潜在空间坐标(低维 embeddings) latent = model.get_latent_representation(adata) # - 也可以对生成分布、去噪表达值等进行预测 denoised = model.get_normalized_expression(adata) # 6. 进一步下游分析 # 用 latent 做聚类、可视化(UMAP/tSNE),或把 denoised 表达用于差异分析等
在实际分析中,你也会看到与 scanpy
配合使用,将低维表示(latent
)存到 adata.obsm
再可视化。
数据规模
硬件环境
超参数设置
max_epochs
(训练轮数)越大,训练越充分,耗时也越长。通常设置在 200~500 轮之间,如果数据规模非常大,也可酌情降低或调高。n_latent
(潜在空间维度)等参数会影响网络规模,进而影响训练时间。大致参考耗时
SCVI.setup_anndata
与 SCVI
类初始化后即可开始训练。如果你刚开始尝试 scVI,建议先在小规模示例数据上测试流程,然后再迁移到完整的数据集,以更好地掌握模型的训练时间和资源需求。
怎么回事
这个提示说明 Jupyter 内核(kernel)意外退出,然后被自动重启了。最常见的原因和排查方向如下:
内存不足(OOM)
代码或依赖库出错
版本冲突或环境不一致
conda env list
、pip list
等确认库版本是否满足依赖要求。GPU/硬件驱动问题(如果你在用 GPU)
监控系统资源
htop
、top
、watch nvidia-smi
等),如果内存或 GPU 显存突然冲顶,则可能需要减少批处理大小(batch size),缩小数据维度,或扩展可用内存。减少数据规模或分步调试
确保依赖库/驱动版本一致
conda
或者官方 Docker 环境,不要在同一个环境里混装过多不同版本的库。检查代码逻辑
简而言之,kernel 自动重启往往是 因为进程被杀死或非正常退出,最常见的就是内存/显存不足或底层依赖库崩溃。可以从以上几条思路入手逐步排查并解决问题。
批次效应是什么
批次效应(Batch effect) 是指在生物实验中,由于不同实验批次(如实验时间、实验设备、实验者、试剂、环境等因素)引起的非生物学变异。这种效应可能会导致在同一生物样本群体中,不同批次间出现系统性差异,使得不同批次之间的样本表现出不同的基因表达模式,从而掩盖或错误解释生物学上的真实差异。
批次效应是单细胞 RNA 测序(scRNA-seq)等高通量数据分析中的一个常见问题,尤其是在多个实验条件或多个技术平台下采集样本时,批次效应可能显著影响结果的准确性。
批次效应的来源非常多样,常见的因素包括:
批次效应可能会在分析结果中产生以下几种影响:
检测批次效应的一些常用方法包括:
为了消除批次效应,可以采取以下几种方法:
设计实验时考虑批次:
批次效应校正方法:
标准化和归一化:
sc.pp.normalize_total
和 sc.pp.scale
),减少因测序深度和技术噪声导致的批次差异。假设你在进行单细胞 RNA 测序实验时,有两个批次的样本:批次 A 和批次 B。在分析时,如果你发现批次 A 中的某些基因表达显著高于批次 B,而实际上批次 A 和批次 B 的样本来源于相同的生物学条件,这可能是由于实验条件差异(如试剂、设备等)造成的批次效应。
通过使用如 ComBat、MNN 等批次效应校正方法,可以调整批次效应,使得分析结果反映的是生物学差异,而非技术上的差异。
批次效应是实验中由不同批次条件引起的系统性差异,这种差异可能掩盖或误导生物学信号的发现。理解并有效处理批次效应,是进行高质量单细胞 RNA-seq 分析的关键步骤。
怎么解决
你看到的 ModuleNotFoundError: No module named 'scvi'
表明当前 Python 环境中并没有安装 scvi-tools
(scVI 的官方 Python 包)。要解决这个问题,你需要先安装并确保在相同的环境中使用。以下是常用的安装方法及注意事项:
(1)使用 conda 安装(推荐)
bashconda install -c conda-forge scvi-tools
或者,如果你想确保安装到特定环境,可以:
bashconda create -n scvi_env python=3.9 conda activate scvi_env conda install -c conda-forge scvi-tools
然后在该环境下启动 Jupyter:
bashconda activate scvi_env jupyter notebook
(2)使用 pip 安装
bashpip install scvi-tools
如果你通过 pip 安装,需要注意在 Jupyter Notebook 中使用的 Python 解释器是否与安装位置一致。如果不一致,要确保 pip install
与 python/jupyter
属于同一环境。
如果安装后依旧报错,通常是因为 Jupyter Notebook 使用了和安装 scvi-tools 不同的 Python 环境。常见解决方法:
bashconda activate scvi_env jupyter notebook
ipykernel
给每个环境单独配置一个内核。例如:
然后在 Jupyter Notebook 中,通过“Kernel -> Change kernel”切换到你创建的这个内核。bashconda activate scvi_env pip install ipykernel python -m ipykernel install --user --name scvi_env --display-name "Python (scvi_env)"
安装完成后,在 Notebook 中执行以下命令看能否正常 import:
pythonimport scvi print(scvi.__version__)
若能打印出版本号,说明安装和环境配置正确,然后再继续你的 scvi 分析流程即可。
leiden 算法
Leiden 算法 是一种用于**图(network)社区检测(community detection)**的聚类算法,它是对广泛使用的 Louvain 算法的改进版。Leiden 算法通常应用于单细胞 RNA-seq 分析中,用于对细胞进行聚类,从而在表达空间中识别具有相似特征的细胞群。
下文将从背景原理、主要特点、在单细胞分析中的使用方式等方面进行简单介绍。
社区检测问题
Louvain 算法
Leiden 算法
在常见的单细胞分析工具中(如 Scanpy 或 Seurat),Leiden 算法常被用作默认或可选的聚类方法。例如,在 Python + Scanpy 的流程里,你会看到:
pythonimport scanpy as sc # 假设 adata 是包含单细胞表达矩阵的数据对象 # 1. 构建近邻图 sc.pp.neighbors(adata, n_neighbors=10, use_rep='X_pca') # 这里可以使用 PCA 后的降维空间 (X_pca) 建立 KNN 图 # 2. Leiden 聚类 sc.tl.leiden(adata, resolution=1.0, key_added="leiden") # 'resolution' 控制聚类的细分程度,越大则社区越细 # 3. 根据聚类结果可视化 sc.pl.umap(adata, color=["leiden"]) # 查看 UMAP 空间中不同簇的分布
adata.obs
中查看对应的标签(如 “leiden”)。resolution
并结合下游的生物学知识(如 marker genes 表达)来判断哪个聚类结果更符合研究需求。resolution
)来获取不同颗粒度的细胞分群结果。Leiden 算法的原始论文:
怎么解决
从错误信息来看:
ImportError: cannot import name 'deprecated' from 'typing_extensions'
说明某个包(可能是 jax
、flax
、或者它们的依赖)正在尝试从 typing_extensions
中导入名为 deprecated
的符号,但当前安装的 typing_extensions
版本并不包含这个符号。
这是版本兼容问题。常见的解决思路是 升级 typing_extensions
,或者把需要它的库和 typing_extensions
同步到合适的版本。你可以尝试以下步骤:
如果使用 conda,可以试试:
bashconda install -c conda-forge typing_extensions --upgrade
或(在当前激活的环境中):
bashpip install --upgrade typing_extensions
之后再次运行脚本,查看是否还会报错。
若升级后仍然报错,可能是其他依赖包的版本与新版本 typing_extensions
不兼容。此时建议:
查看冲突包
conda info --envs
和 conda list
,或使用 conda-forge
/pipdeptree
工具查看依赖树。typing_extensions<某版本>
的包,看是否可以同时升级它们。新建一个干净环境
bashconda create -n scvi_env python=3.9 conda activate scvi_env conda install -c conda-forge scvi-tools jax ...
升级/安装完成后,在同一个环境里打开 Jupyter Notebook,执行:
pythonimport typing_extensions print(typing_extensions.__version__)
检查最终的版本号,并重新运行你的脚本。如果成功不再报错,即说明问题已解决。
typing_extensions
中导入 deprecated
,但该符号只在较新的 typing_extensions
版本中才有(通常 >=4.4.0
)。typing_extensions
,并确保 Jupyter 使用的 Python 环境与安装位置保持一致。若依赖冲突严重,可考虑新建并管理一个干净的 conda 环境来安装所需包。从报错信息可见,PyTorch 在初始化时试图导入其核心扩展模块(通常是 torch._C
),却发生了 NameError: name '_C' is not defined
。这个问题大多与 PyTorch 的安装或环境不兼容 有关。一般是因为:
torch._C
未能正确加载;以下是一些常见的解决思路与排查方法:
在同一个环境中检查 PyTorch 版本
bashconda list | grep torch # 如果用 conda pip show torch # 如果用 pip
或者在 Python 里:
pythonimport torch print(torch.__version__)
若导入报错或版本打印异常,说明安装存在问题。
重新安装 PyTorch
选择与操作系统、Python 版本、CUDA 版本匹配的安装方式。
(如果是 CPU-only 版本,请去掉bashconda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch
cudatoolkit
参数)(也可改成bashpip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu113
cpu
版本或其他 CUDA 版本的下载源,具体参考 PyTorch 官网上的 “Start Locally” 页面)保持与 Python 版本匹配
确保 Jupyter Notebook 使用的内核对应同一个 conda/pip 环境
conda install torch
却在 Jupyter 使用了另一个环境,就会导致导入冲突。ipykernel
,并将内核注册到 Jupyter 中:
然后在 Notebook 里通过 “Kernel -> Change Kernel” 选择正确的环境。bashconda activate your_env pip install ipykernel python -m ipykernel install --user --name your_env --display-name "Python (your_env)"
查看 sys.path
在 Notebook 中运行:
pythonimport sys sys.path
看看是否有意外的路径(如另一个 Python 版本的 site-packages)。若是,则要确保只保留当前环境下的库路径。
module load cuda/11.3
等)。有时原环境里包冲突较多,最简单的办法是新建一个干净 conda 环境,一次性安装所有需要的库。例如:
bashconda create -n scvi_env python=3.8 conda activate scvi_env # 安装 PyTorch(根据需要选 CPU 还是 GPU 版本) conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch # 安装 scvi-tools conda install -c conda-forge scvi-tools
随后,启动并使用这个环境的内核来跑 Jupyter Notebook。如果一切安装成功,import torch
和 import scvi
应该都不会再报错。
torch._C
未被正确加载,多半与 PyTorch 安装或依赖不匹配有关。cellex
Cellex 是一个主要针对单细胞转录组数据的 Python 工具包,由 Broad Institute 等团队开发,用来快速地量化基因在不同细胞群中的表达差异和关联性,辅助下游分析。它的特色在于能够高效计算大规模单细胞数据集的基因-细胞(或基因-基因)相关信息,并支持基于这些计算结果的可视化和基因富集分析。下面是一个简要概述:
计算基因表达统计量:
基因-基因关联分析:
下游可视化与富集:
如果你使用 pip
(并保证 Python 版本兼容,一般 3.7+):
bashpip install cellex
或使用 conda
,先进入/创建一个环境,再执行:
bashconda install -c conda-forge cellex
安装完成后,可以在命令行使用 cellex
命令行工具,也可以在 Python 中 import cellex
直接调用。
Cellex 提供了命令行模式和 Python API 两种接口。一般流程可能是:
cellex gene_stats -i input_expression_data -o output_stats_file
pythonimport cellex as cx # 加载数据(假设是一个 expression_matrix 以及 cell_type 标签) # 做初步处理,比如把数据包装成 cellex 的数据结构 results = cx.calculate_stats(expression_matrix, cell_types=cell_type_labels) # results 即包含每个基因在各细胞群中的表达均值、检测率等信息
Cellex 是专注于快速计算单细胞数据基因统计量和基因-基因相关性的工具,可与其它单细胞分析平台/包配合使用,帮助你更好地理解哪些基因在哪些细胞群中具有显著的表达或关联模式。安装后只需简单几行命令或 API 调用,便可在大规模数据中提取关键的表达信息与基因关联网络,从而加速下游生物学解析。
从错误信息 NameError: name '_C' is not defined
可以看出,这个问题通常出现在 PyTorch 安装过程中,尤其是在加载 PyTorch C 扩展时。具体来说,错误信息说明 PyTorch 可能未能正确加载 C 扩展模块(torch._C
),这通常是由于以下几种原因导致的:
有时,PyTorch 安装文件可能被损坏或不完整。你可以尝试重新安装 PyTorch 来解决问题。
使用 conda 安装 PyTorch(推荐):
bashconda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch
这里的 cudatoolkit=11.3
是针对使用 GPU 的用户。如果你不使用 GPU,可以安装 CPU-only 版本:
bashconda install pytorch torchvision torchaudio cpuonly -c pytorch
使用 pip 安装 PyTorch: 如果你使用 pip,可以尝试以下命令:
bashpip install torch torchvision torchaudio
确保 PyTorch 安装版本与你的 Python 版本和 CUDA 版本兼容。你可以检查你的 Python 版本(例如,3.8 或 3.9)和 CUDA 版本(例如 11.1):
bashpython --version
bashnvcc --version
安装 PyTorch 时,可以根据你当前的 CUDA 版本选择对应的安装命令。例如,如果你使用 CUDA 11.1,可以通过 PyTorch 官方网站选择适合你的版本的安装命令。
如果你的 conda 环境中存在包冲突或不兼容,建议你创建一个新的干净的环境来安装 PyTorch。执行以下步骤:
创建新的 conda 环境:
bashconda create -n torch_env python=3.8 conda activate torch_env
安装 PyTorch:
bashconda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch
如果使用 Jupyter Notebook,确保你在新环境下安装了 ipykernel
并注册该内核:
bashpip install ipykernel python -m ipykernel install --user --name torch_env --display-name "Python (torch_env)"
确保你在 Jupyter Notebook 中使用的是正确的 Python 内核。你可以通过以下命令来检查当前环境中的内核:
Kernel -> Change Kernel
,并确保选择了你当前 Python 环境的内核。这个错误通常是由于 PyTorch 安装过程中的问题,或者是环境配置不当导致的。你可以通过重新安装 PyTorch、确认版本兼容性、清理环境并重新创建环境来解决。
在 Jupyter Notebook 里直接输入 python -m ipykernel install --user --name torch_env --display-name "Python (torch_env)"
会被当作 Python 代码来解释,从而导致 SyntaxError: invalid syntax
。这是因为你正处于 Python 解释器(即 Notebook Cell),而不是在终端/命令行。
要在 Notebook 中运行系统命令,可以有两种方法:
最常见也最简单的做法是打开一个系统终端(或者 Anaconda Prompt),激活你的环境后执行:
bashconda activate torch_env python -m ipykernel install --user --name torch_env --display-name "Python (torch_env)"
这样可以在 Jupyter 中注册一个名为 torch_env
的内核,显示名称为 Python (torch_env)
。
!
来调用 Shell 命令如果你想在 Jupyter Notebook 的 Cell 中完成同样的事情,需要在命令前加一个 !
,告诉 Notebook 这是一个 Shell 命令,例如:
python!python -m ipykernel install --user --name torch_env --display-name "Python (torch_env)"
这样就不会出现语法错误。Notebook 会将这个命令发送给操作系统的 Shell 来执行。
!
前缀来运行 Shell 命令。torch_env
内核。这个错误通常与 PyTorch 没有正确加载其内部 C 扩展 有关,具体表现为 Failed to load PyTorch C extensions: It appears that PyTorch has loaded the 'torch/_C' folder ...
之类提示。以下几点是常见原因与对应的排查/解决思路:
torch
冲突如果你当前工作目录(或其上级目录)里,恰好有一个名为 torch
的 Python 文件或文件夹,会覆盖掉真正的 PyTorch 包,导致在导入 torch
时出现各种奇怪的错误。
torch/
文件夹或 torch.py
文件。torch
看是否还会出现相同报错。即使已经切换到新的内核,也可能存在 PyTorch 安装不完整、版本冲突,或者同一环境下有多套 PyTorch 依赖残留等情况。可以尝试以下步骤:
在新建的环境中重新安装
先卸载现有的 PyTorch 以防冲突:
bashconda remove pytorch torchvision torchaudio --yes
然后重新安装(假设你要 GPU 版,而且 CUDA 版本是 11.3):
bashconda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch
或者安装 CPU-only:
bashconda install pytorch torchvision torchaudio cpuonly -c pytorch
确认安装的 torch 版本
在同一个环境下,打开 Python/conda Prompt,执行:
pythonimport torch print(torch.__version__) print(torch.__file__)
确保 Jupyter 使用同一内核
!which python
或 import sys; print(sys.executable)
看看和你 conda activate
后在终端用 which python
得到的路径是否一致。ipykernel
并正确注册内核,要么在终端里启动 jupyter notebook
确保加载该环境。有时候,PyTorch 的报错“It appears that PyTorch has loaded the torch/_C folder
”也可能出现在下面这种场景:
torch
的文件夹(或类似名字)中运行 Python/Jupyter。请检查:
pwd
(Linux/Mac)或 cd
命令确认自己不在一个名字为 torch
的目录内。sys.path
:在 Notebook 中执行
看看有没有任何奇怪的路径指向了不该指向的“fake torch”或旧的安装位置。pythonimport sys print(sys.path)
若你的机器使用 GPU 版 PyTorch,需要系统层面 GPU 驱动 (NVIDIA driver) 与相应的 CUDA 版本匹配。有时驱动过旧或 CUDA 库缺失,也可能导致加载 C 扩展失败(不过这类错误更常见于 “libxxx.so not found”,而不是 NameError: name '_C' is not defined
)。
看能否成功 import;若成功,再切换到 GPU 版进行尝试。bashconda install pytorch torchvision torchaudio cpuonly -c pytorch
如果以上方法都尝试后依然报同样错误,可能说明原环境有杂乱的依赖或冲突,最省心的做法往往是从零新建一个干净的 conda 环境,一次性安装所需的库:
bashconda create -n scvi_env python=3.9 conda activate scvi_env # 安装 PyTorch conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch # 安装 scvi-tools conda install -c conda-forge scvi-tools # (可选)安装 ipykernel 并注册内核 pip install ipykernel python -m ipykernel install --user --name scvi_env --display-name "Python (scvi_env)"
然后重启 Jupyter,选择 Python (scvi_env)
内核,再次执行 import scvi
和 PyTorch 相关操作。
torch
同名的冲突。torch/_C
”加载失败的问题都能解决。从报错信息可见,pip
在卸载了 Torch 2.4.1 之后又安装了 更早版本 的 Torch(1.12.1+cu113),结果导致 pyro-ppl 1.9.1
和 Torch 出现了依赖冲突:
pyro-ppl 1.9.1 requires torch>=2.0, but you have torch 1.12.1+cu113
也就是说,pyro-ppl 1.9.1 这个包需要的 PyTorch 版本不小于 2.0,而你现在系统里安装的却是 Torch 1.12.1,二者不匹配。pip
在安装/卸载包时有时会出现这样的冲突,由于它的依赖解析器并没有同时考虑所有已安装包的需求,所以就会出现这种“一个包升级了导致另一个包不兼容”的情况。
torch>=2.0
。pip
为了满足其他包的需求(或手动指定了旧版本),将你的 Torch 降级到了 1.12.1
。确定你真正想要的 PyTorch 版本
torch>=2.0
,那你就应该让 PyTorch 保持在 2.0+。重新安装到兼容版本
如果你想保持 Torch 2.4.1(或至少 2.0+),可以强制升级 PyTorch 同时兼容 pyro-ppl 的需求:
bashpip install --upgrade torch==2.4.1 pyro-ppl
或者:
bashpip install --upgrade torch pyro-ppl
(前提是 pip 能找到合适的二进制包,CUDA 版本也匹配;若有问题可以考虑用 conda 或者指定 CUDA 版本。)
如果你想回退 pyro-ppl 到适合 Torch 1.12 的旧版本,可以(在同一环境里)先卸载再指定安装:
bashpip uninstall pyro-ppl pip install "pyro-ppl<1.9" # 示例,具体要看哪个版本兼容 1.12
使用 conda 环境
如果你有大量的科学计算包,conda(尤其是 conda-forge
)有更完善的依赖管理,可以减少类似冲突。
bashconda create -n scvi_env python=3.9 conda activate scvi_env conda install -c conda-forge scvi-tools conda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch
在干净环境中安装
如果当前环境依赖已经很乱,出现大量冲突,最简单的方法往往是新建干净环境,然后按需安装依赖。这样可以避免旧版本/冲突依赖残留。
根据报错信息
ImportError: cannot import name 'MAP_LOCATION' from 'torch.serialization'
这是因为当前的 PyTorch 版本中并没有在 torch.serialization
模块下定义 MAP_LOCATION
这个符号,而你的 pyro 版本(即 pyro-ppl
)在导入它时发生冲突。
通常这是 PyTorch 与 pyro-ppl 版本不匹配 导致的:一方需要某些新的接口或已移动的位置,另一方却缺少或尚未实现。
torch>=2.0
或者至少依赖某些只在较新 PyTorch 版本中才存在的接口。MAP_LOCATION
还不存在或已被移动,导致 pyro-ppl
无法正常 import。如果你想使用当前(较新)版本的 pyro-ppl(比如 1.9.1,需要 PyTorch ≥ 2.0),就要让 PyTorch 与之匹配:
或者bashpip uninstall torch torchvision torchaudio
bashconda remove pytorch torchvision torchaudio
bashpip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
注:
cu118
是 CUDA 11.8 的包,不同版本需更换索引地址。若你只需 CPU 版本,可用--index-url https://download.pytorch.org/whl/cpu
如果使用 conda,则:
bashconda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch
pyro-ppl
:
(或使用bashpip install --upgrade pyro-ppl
conda install -c conda-forge pyro-ppl
)如果都能成功 import 且版本满足,pythonimport torch import pyro print(torch.__version__) print(pyro.__version__)
MAP_LOCATION
报错就应消失。如果你无法升级 PyTorch(比如机器环境限制),可以让 pyro-ppl 回到与 Torch 1.12.x 兼容的旧版本。例如,pyro-ppl 1.8.x 可能仍支持 Torch 1.12。具体做法:
bashpip uninstall pyro-ppl
或检查 pyro-ppl 的 release notes 以找到兼容 Torch 1.12 的版本号。bashpip install "pyro-ppl==1.8.4"
如果不再报pythonimport pyro
MAP_LOCATION
的错误,说明版本匹配成功。当环境混乱、冲突较多时,新建一个干净的 conda 环境最为简单省心,一次性安装所有需求:
bashconda create -n pyro_env python=3.9 conda activate pyro_env # 如果需要 PyTorch 2.x + pyro-ppl 最新 conda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch conda install -c conda-forge pyro-ppl
这样 conda 会自动为你选择可共存的版本。再在该环境中启动 Jupyter Notebook(或安装 ipykernel 后注册内核),即可避免旧环境包冲突。
pyro
里使用了在你当前 PyTorch 版本里并不存在的 MAP_LOCATION
接口,说明两者版本不匹配。这个报错:
TypeError: 'type' object is not subscriptable
通常出现在使用了 Python 3.9+ 才支持的简化类型注解(例如 tuple[float, float]
、list[int]
等)时,而你当前的 Python 环境却不支持这种语法。最典型的场景是:
tuple[float, float]
、list[str]
之类的注解(PEP 585 语法);'type' object is not subscriptable'
。你看到的调用栈中 betas: tuple[float, float] = (0.9, 0.999)
就是典型的 Python 3.9+ 写法。
先检查一下你的 Python 版本号(例如在终端/Notebook 里执行 python --version
或在 Notebook 里 import sys; print(sys.version)
)。如果是 3.8 或更低,很可能就会出现此类注解引发的错误。
而很多最新的深度学习或单细胞分析库(例如某些 scVI 版本、依赖的 optax/chex/jax 也可能使用了这种新语法)要求 Python 3.9 或更高。
升级到 Python 3.9+
降级相关库(不推荐)
手动修复源码(极不推荐)
tuple[float, float]
改回 Tuple[float, float]
并从 typing
中 import Tuple
。但需要在每次更新包后都手动改,很麻烦且风险高。大多数情况下,升级到 Python 3.9 或更高是最省事、最可靠的做法。可以考虑在 conda 中新建一个环境,指定 Python=3.9,然后安装 scVI、PyTorch 等:
bashconda create -n scvi_env python=3.9 conda activate scvi_env # 安装 scvi-tools conda install -c conda-forge scvi-tools # 如果需要 GPU 版 PyTorch conda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch
之后再用这个 scvi_env
来运行 Notebook,就不会遇到 'type' object is not subscriptable'
之类的语法冲突。
'type' object is not subscriptable
解决办法
在 Python 代码中出现 TypeError: 'type' object is not subscriptable
,最常见的原因是 使用了仅在 Python 3.9+ 中才支持的“内置类型下标”注解(PEP 585),而你当前的 Python 版本低于 3.9。例如:
python# Python 3.9+ 新语法: my_tuple: tuple[int, str] = (1, "hello") # 在 Python 3.8 或更早版本中会报错:'type' object is not subscriptable
对于 Python 3.8 及以下,内置类型(如 tuple
, list
, dict
)并不支持用下标的方式直接标注类型,需要用 typing.Tuple
、typing.List
等旧写法:
python# 适用于 Python 3.8 及以下: from typing import Tuple my_tuple: Tuple[int, str] = (1, "hello")
如果条件允许,最简单的办法是把 Python 升级到 3.9 或更高,这样就能原生使用 tuple[int, str]
、list[float]
等简化注解语法,不会出现该错误。
示例:conda 环境升级
bashconda create -n py39_env python=3.9 conda activate py39_env
然后在这个环境里安装并运行你的程序,确保没有低版本 Python 干扰。
typing
写法如果无法升级 Python,可以手动改动代码中的注解,将 tuple[...]
、list[...]
等替换成 typing.Tuple[...]
、typing.List[...]
,例如:
python# 错误用法(适用于 3.9+) betas: tuple[float, float] = (0.9, 0.999) # 兼容 Python 3.7/3.8 的写法 from typing import Tuple betas: Tuple[float, float] = (0.9, 0.999)
如果这是第三方库的源码(比如你下载的某个包),就需要找到对应的文件并手动修改。但更新/重装包后还会被覆盖,因此此法仅作临时应急,不够稳妥。
有时是因为你安装的新版本库强行使用了 PEP 585 语法,但你的 Python 还不支持。可以尝试换用该库早期版本(兼容老 Python)的分支。例如:
bashpip install "somepackage<1.0" # 这里的 <1.0 只是示例,需自己查该包历史
不过,这种做法可能导致其它依赖冲突,需要权衡。
tuple[int, str]
、list[float]
。tuple[...]
改回 Tuple[...]
、list[...]
改回 List[...]
(需 from typing import ...
)。在进行scrnaseq 分析中有两批数据,一批是根瘤菌处理大豆苜蓿的数据,根瘤菌处理大豆苜蓿的数据存放在D:\毕设数据\BC23和D:\毕设数据\BC24,D:\毕设数据\BC26等文件夹里,每个文件夹包括barcode feature matrix 三个文件
另一批是结瘤因子处理的数据,放在D:\毕设数据\CR52,D:\毕设数据\CR54,D:\毕设数据\CR83等文件里
如何在python中对两批数据进行整合,预处理并进行harmony,使用Leiden算法聚类
进行cellex处理,仅保留特异性>0.8的基因
接着进行marker基因注释。marker基因如下:
marker_genes_dict = {
"Epidermal cells": ["Medtr1g043220", "Medtr7g060540"],
"Cortical cells": ["Medtr4g088195", "Medtr4g088160"],
"Endodermal, cortical and epidermal cells": ["Medtr7g074650"],
"Quiescent center and nodule primordium, Niche cells":["Medtr2g098180","Medtr4g065370","Medtr5g031880","Medtr7g080460"],
"Central cylinder and pericycle cells":["Medtr1g041695","Medtr1g075640","Medtr8g069955"],
"Stele cells":["Medtr1g104780","Medtr5g015490","Medtr4g097080","Medtr1g064090"],
"Nodule and lateral root initiation":["Medtr7g099330"]
}
下面给出一个示例性的完整分析流程,演示如何在 Python/Scanpy 环境下:
注意:此示例使用了常见的工作流程及函数写法,实际项目中你可能需要根据测序数据特点、实验设计以及依赖版本做适当修改。下面的代码尽量写得简洁易懂,可作为参考模板。
在开始前,确保你已经在 Python 环境里安装了以下主要依赖包(建议使用 conda):
bashconda create -n scenv python=3.9 conda activate scenv conda install -c conda-forge scanpy harmonypy cellex # 如果需要 GPU 版 PyTorch (scVI/cellex等依赖可能需要), # conda install pytorch torchvision torchaudio cudatoolkit=11.8 -c pytorch
然后在同一个环境下启动 Jupyter Notebook 或 JupyterLab:
bashpip install ipykernel python -m ipykernel install --user --name scenv --display-name "Python (scenv)" jupyter notebook
并在 Notebook 中选择 Python (scenv)
内核。
假设你有以下文件夹结构(10X 输出的 barcodes.tsv
, features.tsv
, matrix.mtx
):
根瘤菌处理
D:\毕设数据\BC23
D:\毕设数据\BC24
D:\毕设数据\BC26
结瘤因子处理
D:\毕设数据\CR52
D:\毕设数据\CR54
D:\毕设数据\CR83
在 Python 中使用 scanpy
提供的 sc.read_10x_mtx
逐一读取,并用 obs['batch']
或其他列标记数据来源,以便后续进行批次校正。演示代码如下:
pythonimport scanpy as sc import anndata import os # 1) 定义文件夹路径(Windows 下注意用 r"..." 原始字符串 或 "\\") root_dirs_bc = [ r"D:\毕设数据\BC23", r"D:\毕设数据\BC24", r"D:\毕设数据\BC26" ] root_dirs_cr = [ r"D:\毕设数据\CR52", r"D:\毕设数据\CR54", r"D:\毕设数据\CR83" ] # 2) 分批读取根瘤菌处理数据 adatas_bc = [] for path in root_dirs_bc: ad = sc.read_10x_mtx( path, var_names='gene_symbols', # 使用基因符号作为 var_names make_unique=True # 若有重复基因名则自动加后缀 ) ad.obs['treatment'] = 'rhizobia' # 标记处理类型 # 也可以区分具体文件来源 ad.obs['sample_id'] = os.path.basename(path) adatas_bc.append(ad) # 3) 分批读取结瘤因子处理数据 adatas_cr = [] for path in root_dirs_cr: ad = sc.read_10x_mtx( path, var_names='gene_symbols', make_unique=True ) ad.obs['treatment'] = 'nod_factor' ad.obs['sample_id'] = os.path.basename(path) adatas_cr.append(ad) # 4) 分别合并 BC 组和 CR 组 adata_bc = adatas_bc[0].concatenate(adatas_bc[1:], batch_key="sample_id", batch_categories=[os.path.basename(p) for p in root_dirs_bc]) adata_cr = adatas_cr[0].concatenate(adatas_cr[1:], batch_key="sample_id", batch_categories=[os.path.basename(p) for p in root_dirs_cr]) # 5) 再将两批合并到一起 adata_all = anndata.concat( [adata_bc, adata_cr], label="treatment_group", # 给新产生的 obs 列命名 keys=["rhizobia", "nod_factor"], join="outer" ) print(adata_all) # 至此,adata_all 包含了两批数据
说明:
- 也可以一步到位用
anndata.concat
直接合并多个AnnData
,关键是保证obs
中能区分不同处理/批次。- 以上合并方法有多种写法,无论
concatenate
还是anndata.concat
都可。- 若数据量巨大,可考虑把合并操作拆分到更高性能的环境中。
在单细胞常规分析中,一般会做如下步骤:
python# 1) 基础过滤:去掉测序质量差或表达过少/过多的细胞,去掉表达太少的基因 sc.pp.filter_cells(adata_all, min_genes=200) # 细胞至少有200个基因 sc.pp.filter_genes(adata_all, min_cells=3) # 基因至少在3个细胞中出现 # 2) 归一化 sc.pp.normalize_total(adata_all, target_sum=1e4) sc.pp.log1p(adata_all) # 3) 识别高变基因 sc.pp.highly_variable_genes(adata_all, flavor='seurat', n_top_genes=2000) adata_all = adata_all[:, adata_all.var['highly_variable']] # 4) 标准化/缩放 sc.pp.scale(adata_all, max_value=10) # 5) PCA 降维 sc.tl.pca(adata_all, svd_solver='arpack')
执行完后,adata_all
就是一个经过初步处理、并在 adata_all.obsm['X_pca']
中保存了 PCA 坐标的对象。
如果要使用 Harmony 对不同样本或处理组进行整合/批次校正,可以先指定要校正的列(例如 sample_id
或 treatment
)。Scanpy 提供了 sc.external.pp.harmony_integrate
接口(需要先 pip install harmonypy
):
pythonimport scanpy.external as sce # 以 sample_id 作为批次信息 sce.pp.harmony_integrate(adata_all, key='sample_id') # 这一步会在 adata_all.obsm 中生成 Harmony 校正后的 PCA 表达,例如 "X_pca_harmony" # 后续建图和聚类可以使用这个空间 sc.pp.neighbors(adata_all, use_rep='X_pca_harmony')
构建 KNN 图后,用 Leiden 算法进行聚类,并可用 UMAP/T-SNE 可视化:
python# 邻近图 # 如果已经用 harmony 校正, 则 use_rep='X_pca_harmony' # 如果未校正, use_rep='X_pca' sc.pp.neighbors(adata_all, use_rep='X_pca_harmony') # Leiden 聚类 sc.tl.leiden(adata_all, resolution=1.0) # resolution 决定聚类多少 # 计算 UMAP sc.tl.umap(adata_all) # 可视化 sc.pl.umap(adata_all, color=['leiden', 'treatment', 'sample_id'])
这样就能看到不同聚类在 UMAP 空间中的分布,也能观察批次/处理之间的差异是否减小。
Cellex 可以快速计算基因在不同细胞群(如 Leiden 聚类)中的表达统计量、相关性等,并给出“特异性(specificity)”指标。下面是一个示例流程,具体操作可参考 Cellex 官方文档。
pythonimport cellex as cx import numpy as np import pandas as pd # 假设想根据 Leiden 聚类来计算基因特异性 # 首先准备一个表达矩阵 X, 以及每个细胞对应的聚类标签 # Cellex 一般要求 (cells x genes) 格式的 ndarray/Pandas DataFrame X = adata_all.X # 稀疏矩阵也可以 cell_types = adata_all.obs['leiden'].values # 计算基因统计量 results = cx.calculate_stats( X, # 表达矩阵 cell_types=cell_types, method='spearman' # 可选 'pearson'/'spearman'/'none' ) # 结果对象里包含对每个基因的特异性等信息 # 例如 results.specificity 可能是一个 DataFrame spec_df = results.specificity # 假设列名叫 'specificity' 或 'value', 具体看实际结构: # 保留特异性 > 0.8 的基因 genes_to_keep = spec_df[spec_df['value'] > 0.8]['gene'].unique() print("Number of genes with specificity > 0.8:", len(genes_to_keep)) # 过滤原 AnnData 中的基因 adata_filtered = adata_all[:, np.isin(adata_all.var_names, genes_to_keep)].copy() print(adata_filtered) # 现在 adata_filtered 只保留了特异性较高的基因
最后,根据已有的 marker_genes_dict,我们可以查看这些 marker 基因在聚类或特定细胞群中的表达分布,或直接进行可视化。例如:
pythonmarker_genes_dict = { "Epidermal cells": ["Medtr1g043220", "Medtr7g060540"], "Cortical cells": ["Medtr4g088195", "Medtr4g088160"], "Endodermal, cortical and epidermal cells": ["Medtr7g074650"], "Quiescent center and nodule primordium, Niche cells": ["Medtr2g098180","Medtr4g065370","Medtr5g031880","Medtr7g080460"], "Central cylinder and pericycle cells": ["Medtr1g041695","Medtr1g075640","Medtr8g069955"], "Stele cells": ["Medtr1g104780","Medtr5g015490","Medtr4g097080","Medtr1g064090"], "Nodule and lateral root initiation": ["Medtr7g099330"] } # 可以遍历这个字典,对每一类 marker 做单独可视化 for cell_type, genes in marker_genes_dict.items(): genes_exist = [g for g in genes if g in adata_filtered.var_names] if len(genes_exist) == 0: continue print(f"{cell_type} => {genes_exist}") sc.pl.umap(adata_filtered, color=genes_exist, title=cell_type)
这样就可以在 UMAP 上看到各 marker 基因的表达情况,从而推断各个 Leiden 聚类可能对应的细胞类型。
若需要更系统的 marker 基因识别,也可用
sc.tl.rank_genes_groups(adata_filtered, groupby='leiden')
对所有簇做差异表达分析,然后结合上述人工注释的 marker 进行对照。
sc.read_10x_mtx
+ concatenate
/ concat
读入多个文件夹的单细胞矩阵,并在 obs
中标注处理/批次信息。X_pca_harmony
并用它构建图。sc.tl.leiden
后可 UMAP 可视化,查看聚类与批次/处理的关系。sc.pl.umap
等方式可视化表达分布,辅助鉴定细胞类型。这套流程基本覆盖了多批次 scRNA-seq 数据整合、批次效应校正、聚类、Cellex 分析、marker 注释的主要环节,可供你在大豆/苜蓿根瘤相关的单细胞研究中参考与实践。根据具体需求,你还可以在每一步调整参数(例如分辨率、过滤阈值、选择性地做 batch key)以获得最佳的生物学解释。
从错误信息来看,numpy
已经移除了 np.float
这个别名(在 NumPy 1.20
版本中就已废弃,NumPy 1.24
开始彻底移除)。因此,当你的代码或者某个三方库里还在使用 np.float
这个写法时,就会出现:
AttributeError: module 'numpy' has no attribute 'float'
将 np.float
改成原生的 float
np.float
,可以直接替换成内置类型 float
,等效而且更符合当前规范:
python# 原:data_array.astype(np.float) # 改: data_array.astype(float)
np.float64
。将 np.float
改成 np.float64
pythondata_array.astype(np.float64)
如果是第三方库的内部调用
scanpy
, scipy
, pandas
等)还没更新,内部依旧写着 np.float
。numpy<1.20
,以兼容旧写法:
但这样可能会引起其他包不兼容,需要平衡利弊。bashpip install "numpy<1.20"
np.float
、np.int
, np.bool
并改成 float
、int
、bool
或者对应的 np.float64
、np.int32
、np.bool_
等即可。如果升级后仍报错,只好暂时降级 NumPy:bashpip install --upgrade packagename
不过降级 NumPy 有时会造成新旧库冲突,需要留意是否影响其他包。bashpip install "numpy<1.20"
自 NumPy 1.20 起,np.float
、np.int
、np.bool
等别名都被弃用并已在更高版本里移除。最简单的修复方法是用 Python 内置类型 float
、int
、bool
或 NumPy 明确类型 np.float64
、np.int32
替代即可;如果是第三方库导致,就升级该库或回退 NumPy 版本来解决。
出现
BackendUnavailable: Cannot import 'setuptools.build_meta'
说明 pip 在尝试安装包时,无法调用 setuptools.build_meta
这个后端来构建/解析包的元数据。通常是因为 pip 或 setuptools 本身版本过旧或损坏,或环境混乱导致的冲突。以下几种方法通常可解决:
先在当前环境里升级这几个基础工具,然后再安装你想要的包:
bashpython -m pip install --upgrade pip setuptools wheel
有时,如果是 Anaconda/conda 环境,也可试:
bashconda update pip conda update setuptools conda install wheel
升级后再执行:
bashpip install "numpy<1.20"
大多数情况下,这就能解决 Cannot import 'setuptools.build_meta'
报错。
如果上述方法仍失败,可能当前环境包冲突过多。可新建一个干净的 conda 环境并一次性安装所需版本:
bashconda create -n pyenv python=3.9 conda activate pyenv conda install numpy=1.19
这样由 conda 负责依赖管理,减少手动 pip 安装带来的冲突风险。
在极少数情况下,网络不稳定或权限不足,也会导致 pip 拿不到最新的 setuptools
/wheel
文件。
--trusted-host
、--extra-index-url
等参数后再试。BackendUnavailable: Cannot import 'setuptools.build_meta'
通常是因为 pip/setuptools 过旧或损坏,导致无法调用构建后端。pip setuptools wheel
一般能解决;若仍不行,建议新建 conda 环境一次性安装所需包。