十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Jupyter Notebook与Scanpy入门:单细胞分析实战指南

Jupyter Notebook与Scanpy入门:单细胞分析实战指南 Jupyter Notebook 算是目前数据分析、教学和生物信息学里最常用的交互式环境没有之一。Scanpy 则是单细胞 RNA 测序数据分析绕不开的 Python 库。这次我们就把两者串起来讲先搞定 Jupyter Notebook 从安装到日常会用到的操作再用一个典型的单细胞分析流程把 Scanpy 的基本用法跑通。如果你正准备入门单细胞数据分析或者只是想把 Jupyter Notebook 的基础操作彻底弄明白这篇文章可以直接收藏。下面内容会覆盖安装方式、启动步骤、常见报错排查、Scanpy 的核心数据结构与分析流程以及哪些坑应该提前避开。1. 核心能力速览先把两个工具的能力边界说清楚方便你判断自己是否需要继续往下看。能力项说明工具类型Jupyter Notebook 是交互式 Web 编辑器Scanpy 是单细胞分析 Python 库核心用途Notebook 用于写代码、跑实验、记录结果Scanpy 用于单细胞 RNA-seq 数据预处理、聚类、可视化操作系统Windows、Linux、macOS 均支持安装方式pip、conda、Anaconda 集成启动方式命令行执行jupyter notebook浏览器自动打开是否支持 APIJupyter 提供 Kernel 与 REST API日常使用不需要是否支持批量任务可将 Notebook 转换为.py脚本后用命令行批量执行与 PyCharm 配合支持在 PyCharm 中直接使用 Jupyter Notebook适合场景单细胞分析教学、科研数据处理、算法原型验证、数据可视化从材料看Jupyter Notebook 与 Jupyter Lab 是两套界面前者布局简单、单文档为主后者支持多面板、插件生态更丰富。如果你只在单个 Notebook 里工作两者差异不大如果经常同时打开多个 Notebook 或脚本Lab 体验更好。Scanpy 对硬件的要求主要集中在内存。参考真实单细胞数据分析经验数千个细胞的矩阵在 16GB 内存的笔记本上可以跑数万细胞建议用 32GB 以上内存或者服务器节点。GPU 并不是 Scanpy 的必需项大部分操作是 CPU 密集型的矩阵计算和近邻图构建。是否支持 50 系显卡这类问题在 Scanpy 场景下基本不用考虑它不依赖 CUDA 加速。2. 适用场景与使用边界Jupyter Notebook 的适用范围非常广从 Python 入门教学到数据清洗、机器学习实验、论文图表绘制都可以用它。Scanpy 则是单细胞转录组数据分析的专用工具典型任务包括读入 10x Genomics 的矩阵数据。质量控制过滤低质量细胞和基因。数据归一化和对数化。高变基因筛选。PCA 降维、UMAP/t-SNE 可视化。细胞聚类与标记基因分析。批量整合与差异表达分析。它不适合什么场景如果你需要生产环境的高并发 API 服务或者要在超大数据集上做分布式计算Scanpy 不是第一选择除非配合 Scanpy 生态中的分布式后端或者使用独立的单细胞流程框架。Jupyter Notebook 也不适合作为自动化调度平台长时间训练或批量处理任务建议写成 Python 脚本后用nohup或任务调度系统执行。关于使用边界必须明确几点。单细胞数据往往来自医院、科研机构或公共数据库涉及人类样本时可能包含敏感的基因信息。无论是使用公共数据集还是自有数据都应该确认数据来源合规涉及人类受试者数据时要有伦理审批和知情同意。Scanpy 提供了数据读取与输出的能力但并不附带任何授权判断论文复现和商用场景下需要自行确认数据许可。此外分析结果不能直接作为临床诊断依据。单细胞数据分析的结论受到样本质量、参考注释、参数选择等多方面影响在科研论文中使用没有问题但涉及临床决策时需要额外的验证流程。3. 环境准备与前置条件开始之前先确保本机环境满足基本要求。下面给出一套通用检查清单实际版本以你自己环境为准。3.1 操作系统与 Python 环境Windows 10/11、Ubuntu 20.04、macOS 12 均可。Python 版本建议 3.9 到 3.12。Scanpy 对 Python 版本要求比较宽容但过老的 3.7 和过新的 3.13 可能遇到依赖兼容问题。包管理工具建议使用 Anaconda 或 Miniconda。不是必须但对科学计算生态最友好可以避免很多依赖冲突。3.2 硬件与内存建议数据规模最低内存建议说明数千细胞8GB可以在普通笔记本上运行数万细胞16GB - 32GB建议关闭其他大型程序数十万细胞64GB 以上推荐服务器或租用云主机Scanpy 的大部分运算不会用到 GPU主要瓶颈是内存。当你读取一个包含数万细胞、数万基因的表达矩阵时内存占用会快速上升。如果内存不够可以先对数据进行筛选或者在读入时只保留特定基因。3.3 磁盘空间Scanpy 本身只占用几百 MB但原始数据文件可能很大。10x 格式的 HDF5 文件从几百 MB 到几个 GB 不等。建议为每个项目单独建立数据目录不要和系统盘混在一起。4. 安装部署与启动方式下面按照“使用 conda 管理环境”的路线来安装这也是最多教程推荐的组合方式。4.1 创建虚拟环境并安装 Jupyter# 使用 conda 创建 Python 3.10 环境 conda create -n scanpy_env python3.10 -y # 激活环境 conda activate scanpy_env # 安装 jupyter notebook pip install jupyter notebook # 验证版本 jupyter --version如果你希望使用 Anaconda 自带的 Jupyter安装 Anaconda 后在 Anaconda Prompt 中直接执行jupyter notebook就能启动不需要额外安装。还有一种常见情况PyCharm 用户不想在终端启动 Notebook。这时可以在 PyCharm 中安装 Jupyter 插件然后新建.ipynb文件选择需要使用的 KernelPyCharm 会自动调用本机 Jupyter。这里有一个细节PyCharm 中使用的 Kernel 要和你安装 Scanpy 的环境一致否则会出现ModuleNotFoundError: No module named scanpy。4.2 安装 Scanpy# 在同一个 scanpy_env 环境中安装 scanpy pip install scanpy # 如果需要读取 10x 的 h5 文件还需要安装 h5py pip install h5py # 建议安装常用扩展库 pip install leidenalg python-igraphleidenalg和python-igraph用于 Leiden 聚类算法Scanpy 默认使用这一算法。如果这两个库没有安装运行sc.tl.leiden时会报错所以建议一次性装好。安装完成后可以用下面命令确认关键包版本python -c import scanpy as sc; print(sc.__version__) python -c import jupyter; print(jupyter.__version__)如果输出正常说明环境已经可用。4.3 启动 Jupyter Notebook在项目目录下打开终端进入你要存放 Notebook 的目录然后执行jupyter notebook启动成功后终端会输出类似下面的访问地址http://localhost:8888/tree默认端口是 8888如果被占用会自动换成 8889 或其他端口。浏览器打开后点击右侧New按钮选择 Python 3 内核就能新建一个 Notebook。如果你希望指定端口启动jupyter notebook --port9999如果要允许局域网内其他机器访问需要额外配置。这里不展开因为默认绑定localhost对日常本地开发更安全。4.4 在 Jupyter Lab 中打开如果你安装了 Jupyter Lab可以用jupyter labJupyter Notebook 和 Jupyter Lab 的区别前面已经提到简单说 Lab 是多标签、多面板的集成环境Notebook 是更轻量的传统界面。两者打开的都是同一种.ipynb文件因此不存在“文件不兼容”的问题。5. 功能测试与效果验证安装完成后我们通过几个实际测试来确认环境是否正常同时把 Jupyter Notebook 的基础操作过一遍。5.1 基础计算测试新建 Notebook 后在第一个单元格输入print(Hello, Jupyter and Scanpy) 2 3点击运行按钮或者按快捷键Shift Enter下方会输出Hello, Jupyter and Scanpy和5。这说明 Python 内核已经正确连接。Jupyter Notebook 最常见的一个特性是“一个单元格对应一个变量作用域”。如果你在第一个单元格定义了变量后面的单元格可以直接使用不需要重新定义。这是它比写脚本更适合探索性分析的原因之一。5.2 魔法命令测试Jupyter 支持很多%开头的魔法命令下面几个很常用# 查看当前工作目录 %pwd # 列出目录下文件 %ls # 统计单元格运行时间 %time sum(range(1000000)) # 查看变量占用的内存 %memit%time可以用来看单行代码的执行时间%%time加在单元格开头可以统计整个单元格的运行时间。5.3 当前目录与文件路径确认数据分析里最头疼的问题之一就是文件读不到。在 Notebook 中当前目录默认是启动 Jupyter 时所在目录不是 Notebook 文件所在目录。如果你在D:\data下启动 Jupyter然后在D:\data\notebooks下打开了 Notebook它的工作目录仍然是D:\data。调用下面命令验证import os print(os.getcwd())如果和你预期不一致可以使用os.chdir()切换或在读取数据时写绝对路径import scanpy as sc # 建议使用绝对路径避免目录混淆 data_path /path/to/your/data.h5ad adata sc.read_h5ad(data_path)5.4 Scanpy 读取数据测试Scanpy 支持多种数据格式最常用的有.h5ad、10x 的matrix.mtxbarcodes.tsvfeatures.tsv组合以及.h5文件。测试读取一个.h5ad文件import scanpy as sc # 设置图像风格 sc.settings.set_figure_params(dpi100, facecolorwhite) # 读取数据 adata sc.read_h5ad(sample_data.h5ad) # 查看数据概要 print(adata)输出会显示一个 AnnData 对象的摘要类似于AnnData object with n_obs × n_vars 10000 × 20000 obs: batch, cell_type var: gene_symbols uns: neighbors, pca, umap obsm: X_pca, X_umap这里n_obs是细胞数量n_vars是基因数量。看到这个输出说明 Scanpy 安装正常数据读取成功。如果读取 10x 格式的matrix.mtx流程稍有不同import scanpy as sc adata sc.read_10x_mtx( path/to/filtered_gene_bc_matrices/hg19/, var_namesgene_symbols, cacheTrue )注意read_10x_mtx函数的路径应该指向包含matrix.mtx的文件夹而不是直接指向文件本身。如果路径不对会报错找不到文件。5.5 数据质量控制与过滤拿到 AnnData 对象后第一个步骤通常是质控。Scanpy 里最基本的质控指标有三个每个细胞的基因计数、每个细胞的总 UMI 计数、每个细胞的线粒体基因比例。# 计算质量控制指标 sc.pp.calculate_qc_metrics(adata, qc_vars[mt-], percent_topNone, inplaceTrue)在人类数据中线粒体基因通常以MT-开头。计算出指标后可以用小提琴图观察分布sc.pl.violin(adata, keys[n_genes_by_counts, total_counts, pct_counts_mt-], multi_panelTrue)看到图后你需要根据分布情况设置过滤阈值。常见做法是保留基因数在 200 到 5000 之间、线粒体比例低于 20% 的细胞但阈值需要根据具体数据调整。sc.pp.filter_cells(adata, min_genes200) sc.pp.filter_genes(adata, min_cells3) # 线粒体比例过滤 adata adata[adata.obs[pct_counts_mt-] 20, :].copy() # 再次查看结果 print(adata)这一步的输出是过滤后的 AnnData 对象细胞数和基因数会明显减少。5.6 归一化、高变基因、降维与聚类下面是一段标准的 Scanpy 流程示例import scanpy as sc # 1. 归一化与对数化 sc.pp.normalize_total(adata, target_sum1e4) sc.pp.log1p(adata) # 2. 高变基因筛选 sc.pp.highly_variable_genes(adata, min_mean0.0125, max_mean3, min_disp0.5) sc.pl.highly_variable_genes(adata) # 3. 数据标准化 sc.pp.scale(adata, max_value10) # 4. PCA 降维 sc.tl.pca(adata, svd_solverarpack) sc.pl.pca_variance_ratio(adata, n_pcs50) # 5. 邻居图构建 sc.pp.neighbors(adata, n_neighbors15, n_pcs30) # 6. UMAP 降维 sc.tl.umap(adata) sc.pl.umap(adata, colorbatch) # 7. 聚类 sc.tl.leiden(adata, resolution0.5) sc.pl.umap(adata, colorleiden)每一步都有对应的输出sc.pl.highly_variable_genes输出高变基因散点图。sc.pl.pca_variance_ratio输出主成分方差占比图。sc.pl.umap输出 UMAP 降维图每个点代表一个细胞。sc.pl.umap加colorleiden显示聚类结果。判断流程是否成功最直观的标准就是 UMAP 图上是否出现有意义的细胞群。如果所有细胞挤成一团可能原因是高变基因筛选参数不合适或 PCA 维度选择太低。可以调大n_pcs或调整resolution参数。5.7 标记基因分析聚类完成后可以计算每个簇的标记基因sc.tl.rank_genes_groups(adata, groupbyleiden, methodwilcoxon) sc.pl.rank_genes_groups(adata, n_genes20, shareyFalse)输出的热图和表格会告诉你每个簇高表达的基因是什么。结果保存为表格result sc.get.rank_genes_groups_df(adata, group0) result.to_csv(cluster0_markers.csv, indexFalse)这一步在实际数据分析中很有用可以用来注释细胞类型。6. Notebook 转脚本与批量任务处理Jupyter Notebook 的交互式体验很好但真正要跑大批量分析时它不是一个好的执行载体。实际项目中更常见的做法是先在 Notebook 里完成流程开发和调试然后把核心代码导出为.py脚本再用命令行批量执行。Jupyter 提供了命令行转换工具# 将 notebook 导出为 python 脚本 jupyter nbconvert --to script analysis.ipynb转换后会生成analysis.py其中包含 Notebook 里的所有代码原 Markdown 内容会变成注释。假设你需要对 10 个样本分别跑同一套分析可以写一个批量脚本import subprocess import os samples [sample1, sample2, sample3, sample4, sample5] for sample in samples: # 每个样本设置独立输入输出目录 env os.environ.copy() env[SAMPLE_NAME] sample env[INPUT_PATH] f./data/{sample}/matrix.mtx env[OUTPUT_DIR] f./results/{sample} # 调用分析脚本 subprocess.run( [python, analysis.py], envenv, checkTrue )在analysis.py内部通过os.environ读取对应的环境变量import os sample_name os.environ.get(SAMPLE_NAME, default) input_path os.environ.get(INPUT_PATH, ) output_dir os.environ.get(OUTPUT_DIR, ./results) print(fProcessing sample: {sample_name}) # 后续分析代码使用 input_path 和 output_dir这种方式的优势在于不需要人工打开每个 Notebook 点运行。可以加上日志记录。出错时可以通过try/except捕获异常。避免 Notebook 长时间挂起导致连接掉落。如果你想在 Notebook 中直接调用外部脚本也可以使用!python analysis.py这种 shell 命令方式但不推荐在交互式环境中跑长任务。7. 资源占用与性能观察Scanpy 和 Jupyter Notebook 都属于内存敏感型工具下面重点说资源占用如何观察和优化。7.1 如何观察内存和 CPU 占用最直接的方法是使用系统自带的任务管理器。Windows 上按Ctrl Shift Esc打开任务管理器在“进程”列表中找到python观察内存占用。Linux 上可以用top或htop。在 Notebook 内可以用 psutil 查看当前 Python 进程的占用import psutil import os process psutil.Process(os.getpid()) print(f内存占用: {process.memory_info().rss / 1024 ** 3:.2f} GB) print(fCPU 使用率: {process.cpu_percent(interval1):.1f}%)在运行 Scanpy 的sc.pp.neighbors或sc.tl.umap时内存占用会有明显上升。尤其 UMAP 会重复多次近邻计算数据量大时耗时较长。7.2 哪些操作最耗资源操作资源消耗特点优化建议读取大文件磁盘 I/O 和内存先用read_10x_mtx的cacheTrue参数缓存高变基因筛选CPU 计算通常很快不用过度优化归一化内存不会特别大邻居图构建CPU 和内存设置合理的n_neighbors不要盲目调大UMAP 降维CPU 密集数据量大时可以增大min_dist以加速Leiden 聚类内存依赖图结构多层迭代时耗时增加7.3 降低内存占用的方法一是过滤低质量细胞和基因。很多数据集中大部分基因在少数细胞中表达过滤掉后矩阵明显减小。二是使用backed模式。Scanpy 支持不把所有数据读入内存而是从磁盘按需读取adata sc.read_h5ad(large_data.h5ad, backedr)但要注意backed模式下很多操作是受限的只有读取部分支持聚类和降维通常还是需要全量加载。三是用单精度浮点数。Scanpy 内部很多数据矩阵默认是float32相比float64内存减半。7.4 启动 Jupyter 时端口冲突启动 Jupyter 报Port 8888 is already in use说明端口被占用。此时 Jupyter 会自动使用下一个可用端口但如果你希望固定端口可以先查看端口占用# Windows netstat -ano | findstr :8888 # Linux / macOS lsof -i :8888找到占用进程的 PID 后再根据情况决定是否终止进程或者直接换一个端口启动。8. 常见问题与排查方法下面按高频问题整理一份排查表覆盖 Jupyter Notebook 和 Scanpy 两个层面的常见故障。问题现象可能原因排查方式解决方案Windows 启动 Jupyter 后浏览器空白浏览器兼容问题、Jupyter 服务未完全启动查看终端日志确认输出里是否出现http://localhost:8888的地址换 Chrome/Edge 访问刷新页面清除浏览器缓存换端口启动在终端确认服务状态Notebook 无法连接 KernelKernel 进程崩溃或 Python 环境不一致查看 Jupyter 终端输出确认使用的 Kernel 是否来自当前虚拟环境重启 Kernel确认python -c import scanpy可正常导入更换其他浏览器打开默认浏览器不兼容复制终端输出的完整 URL 到其他浏览器地址栏直接复制http://localhost:8888/tree在新浏览器打开PyCharm 中使用 Jupyter 报错Kernel 选择错误查看 PyCharm 右下角 Kernel 名称确认是否为scanpy_env在 PyCharm 设置中切换 Kernel确认scanpy_env在 Jupyter 的 Kernel 列表中ModuleNotFoundError: No module named scanpyKernel 环境不是安装 Scanpy 的环境pip list | grep scanpy重新创建 Kernelpython -m ipykernel install --user --name scanpy_env --display-name Python (scanpy_env)启动 Jupyter 后地址栏是localhost但页面打不开防火墙拦截、代理设置检查终端输出是否有报错信息关闭系统代理在命令行执行jupyter notebook --no-browser手动复制 URL 到浏览器端口 8888 被占用之前有 Jupyter 进程残留netstat -ano | findstr :8888结束占用进程或使用--port8889读取.h5ad文件报错文件路径不对或文件损坏检查文件是否存在打印工作目录使用绝对路径重新下载数据文件sc.pp.neighbors非常慢数据量太大、n_neighbors设置过大检查数据规模观察 CPU 使用率先过滤低质量细胞调整n_neighbors为 10-15UMAP 图上细胞聚成一团PCA 维度选择不合适或高变基因筛选不当查看sc.pl.pca_variance_ratio曲线增大n_pcs调整高变基因参数检查数据是否经过 log1p聚类结果全是同一个簇resolution参数太小查看leiden聚类结果分布增大resolution例如从 0.5 调到 1.0画图中文显示为方框系统缺少中文字体检查 matplotlib 字体在代码中指定中文字体路径或使用英文标签内存不足导致 Kernel 重启数据量超过物理内存查看系统内存占用过滤数据分段处理使用 backed 模式读取上面这些情况是刚开始接触 Jupyter Notebook 和 Scanpy 时最常踩的坑。遇到报错先看终端日志不要只盯着浏览器页面。浏览器白屏不代表 Jupyter 没启动出错信息通常都打印在启动终端的控制台里。9. 最佳实践与使用建议掌握了基础操作和常见问题排查之后下面这些工程化建议可以帮你少走弯路。9.1 第一次先跑小数据入门阶段不要直接拿几十万细胞的大数据集测试。可以从 Scanpy 官方内置的pbmc3k数据集开始跑通完整流程后再切换自己的数据。import scanpy as sc adata sc.datasets.pbmc3k()这个数据集只有几千个细胞几秒内就能完成预处理、聚类和可视化。流程跑通了再换真实数据就不会手忙脚乱。9.2 环境隔离不要在系统 Python 里直接安装 Scanpy。科学计算库依赖很复杂很容易出现 A 库需要 numpy 1.x、B 库需要 numpy 2.x 的冲突。使用 conda 创建独立虚拟环境是成本最低的规避方式。9.3 目录管理建议按下面的结构组织你的项目project/ ├── data/ # 原始数据 │ └── sample1/ ├── notebooks/ # Jupyter Notebook 文件 ├── scripts/ # 导出后的 Python 脚本 ├── results/ # 图表和表格输出 │ ├── figures/ │ └── tables/ ├── logs/ # 批处理日志 └── README.md # 记录参数和数据处理细节有了清晰目录笔记本里的路径就不会混乱批处理脚本也更容易管理。9.4 加日志与失败重试批量任务一定要有日志和异常捕获。Jupyter Notebook 里跑一个分析报错了你可以直接改单元格重新运行但脚本在服务器上跑了一天后报错没有日志就非常被动。import logging import traceback logging.basicConfig( filenamelogs/analysis.log, levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s ) try: # 分析代码 adata sc.read_h5ad(data_path) logging.info(fLoaded data with {adata.n_obs} cells) except Exception as e: logging.error(fError: {e}) logging.error(traceback.format_exc())9.5 数据合规与授权再强调一次单细胞数据涉及人类基因信息时需要确认数据来源和授权范围。公共数据库下载的数据通常会有许可协议例如需引用原论文。自有数据要确保符合机构和研究伦理要求。分析结果对外发布时也要确认不涉及个人身份信息泄露。9.6 复现性写分析流程时尽量把关键参数写进代码而不是靠手动修改。比如过滤阈值。PCA 维数。UMAP 参数。聚类分辨率。如果要发布论文或报告建议记录 Scanpy 版本和 Python 版本因为不同版本的分析结果可能有细微差异。import scanpy as sc import session_info # 输出环境中所有包的版本 session_info.show()这样别人复现时能准确知道你的运行环境。9.7 不要把所有功能塞进一个 NotebookNotebook 并不是越长越好。一个 200 个单元格的 Notebook运行到一半 Kernel 重启前面的状态全部丢失是非常糟糕的体验。建议按照阶段拆分为多个 Notebook01 数据读取与质控。02 降维与聚类。03 标记基因与细胞类型注释。04 可视化与结果导出。每个 Notebook 负责一个阶段。如果前一个阶段的结果要传给下一个阶段直接保存中间结果adata.write_h5ad(results/pbmc3k_processed.h5ad)后续 Notebook 只需要一行代码读取不依赖前面的内存状态。10. 总结与下一步这次我们从零开始把 Jupyter Notebook 的基本操作、安装方式、常见问题和 Scanpy 的单细胞分析入门流程都过了一遍。最值得记住的几点是Jupyter Notebook 的关键不是编辑器本身而是交互式运行和可视化反馈这让单细胞分析的探索过程非常顺畅。Scanpy 的核心是 AnnData 对象掌握adata.obs、adata.var、adata.obsm这几个结构就能理解大部分分析逻辑。环境隔离、目录管理、脚本化执行和日志记录是让分析流程从“能跑”升级为“可靠”的关键。下一步建议先跑通sc.datasets.pbmc3k()的完整流程。在那之后你可以尝试接入自己的 10x 数据。做批次效应整合例如sc.external.pp.harmony_integrate。使用sc.tl.score_genes做模块打分。借助sc.tl.dendrogram做聚类树可视化。将 Notebook 流程沉淀为可复用的 Python 脚本。易踩的坑集中在两个地方一是 Kernel 环境错误导致找不到 Scanpy二是路径混乱导致读不到数据。把这两个问题先解决后面的分析流程基本能顺利推进。如果你正在准备单细胞数据分析的工作流建议保留一套最小可运行配置把本文中的核心代码保存为一个模板 Notebook。这样每次开新项目时不用从空白开始直接改路径和参数就能进入实际分析。
返回列表