尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Jupyter Notebook + Scanpy:单细胞数据分析环境搭建与完整流程实战

Jupyter Notebook + Scanpy:单细胞数据分析环境搭建与完整流程实战 如果你正在做单细胞测序数据分析大概率会遇到这样一个尴尬的场景别人的教程里代码一行接一行跑得飞快图也漂亮到了自己电脑上光是搭建环境、组织代码、调试参数就已经耗掉大半天。更常见的情况是你已经在用 Python 写分析脚本但每个步骤的中间结果只能靠 print 和 matplotlib 硬看改一个过滤阈值就要把整个流程重新跑一遍。这个问题的根源往往不是你不会写代码而是缺少一个合适的交互式分析环境。Jupyter Notebook 恰恰就是为这种“边写边看、边调边想”的场景设计的。而对于单细胞数据分析Python 生态里最主流的框架 Scanpy它的官方教程、社区案例几乎全部基于 Jupyter Notebook 展开。可以这么说Jupyter Notebook 是 Scanpy 的最佳运行载体而 Scanpy 是 Jupyter Notebook 最能发挥价值的分析场景之一。这篇文章不是简单罗列 Notebook 的快捷键也不是把 Scanpy 的文档翻译一遍。我会从一个完整的单细胞数据分析流程出发把 Jupyter Notebook 和 Scanpy 结合起来讲清楚你为什么要用 Notebook 做单细胞分析、环境和依赖怎么装、Windows 下常见的空白页面问题怎么解决、如何在 PyCharm 里使用 Notebook、以及 Scanpy 从数据读取到聚类注释的完整代码怎么落地。读完这篇文章你应该能独立搭建一套“Jupyter Notebook Scanpy”的单细胞数据分析环境并跑通一条标准分析流程。1. 这篇文章真正要解决的问题很多初学者对 Jupyter Notebook 和 Scanpy 的关系存在误解。有些人觉得 Notebook 只是一个“高级记事本”用 PyCharm 写脚本也能替代有些人则认为 Scanpy 只是 Seurat 的 Python 替代品换个工具而已。这两种理解都过于简单了。先看 Jupyter Notebook 解决了什么问题。在传统脚本开发模式下你写一个analysis.py从头跑到尾中间某个步骤出错就要修完从头再来。单细胞数据分析恰恰是最不适合这种模式的工作之一它高度依赖人工判断每个过滤阈值都需要反复调整每次调整都要配合可视化结果观察效果分析过程本身就是一条需要不断回溯、修正的探索链。Notebook 把代码拆成一个一个 Cell你可以只运行其中一个 Cell看到结果再决定下一步怎么改。这种交互方式的改变直接决定了单细胞分析的效率。再看 Scanpy 解决了什么问题。单细胞转录组数据本质上是一个巨大的稀疏矩阵动辄数万基因、数万细胞。传统的数据处理工具很难支撑这种规模。Scanpy 基于 AnnData 数据结构底层借助 NumPy、SciPy、pandas 等科学计算库实现高效运算同时把数据过滤、归一化、降维、聚类、差异表达、可视化整合成一套统一 API。更重要的一点是Scanpy 的数据结构设计非常符合单细胞分析的习惯它把表达矩阵、细胞元信息、基因元信息、降维结果放在同一个对象里分析过程中的每一步结果都可以被记录下来。如果把单细胞数据分析比作做菜Jupyter Notebook 是厨房操作台Scanpy 是完整的厨具套装。操作台决定了你下厨的节奏和效率厨具决定你能做出口味多稳定的菜品。很多人只关注厨具却低估了操作台的重要性。这篇文章适合以下读者刚接触单细胞数据分析想用 Python 生态完成分析但不知道如何下手。已经装了 Anaconda 或 Jupyter Notebook但遇到启动空白、环境混乱、不知道怎么在 PyCharm 里使用等问题。会跑 Scanpy 基础教程但不清楚每一步的输入输出是什么也不知道分析结果如何解读。想从 R 语言的 Seurat 迁移到 Python 生态需要理解两种工具的核心差异。2. 为什么单细胞数据分析需要 Jupyter Notebook2.1 分析流程的探索性质单细胞数据分析不是一条直线的 pipeline。以标准的 10x Genomics 数据处理为例你需要依次完成质控过滤、归一化、高变基因筛选、PCA 降维、UMAP/tSNE 可视化、聚类、marker 基因鉴定、细胞类型注释。表面上看这是一个固定顺序但实际操作中每步都可能回退。比如你完成了聚类发现某个 cluster 可能是双细胞或低质量细胞就需要回到质控步骤调整过滤阈值重新跑下游分析。这种“前进两步、后退一步”的工作模式用传统脚本会非常痛苦。你不得不注释掉大段代码或者用全局变量控制流程开关。而在 Notebook 中每个步骤天然是一个 Cell你可以随时修改任意一个 Cell 并重新运行后面的分析结果会基于新结果继续。这种灵活性不是脚本编辑器能提供的。2.2 可视化和代码的无缝结合单细胞分析的每个重要决策都依赖可视化结果。过滤阈值选多少要看基因数分布图和高变基因图PCA 选多少个主成分要看方差贡献率图聚类分辨率选多少要看 UMAP 图上 cluster 的分布是否合理。Jupyter Notebook 的 Cell 输出可以直接内嵌 matplotlib、scanpy 等库生成的图像而且支持 Retina 高清显示。你不需要像传统脚本那样把图片保存成文件再打开也不需要频繁切换窗口。代码和对应的图放在同一个 Cell 里分析过程的可读性和可复现性都大幅提升。2.3 逐步构建分析的中间产物单细胞分析有一个很实用的技巧把每一个中间结果保存下来方便后续回溯。比如过滤后的数据存一份filtered.h5ad聚类后的数据存一份clustered.h5ad。在 Notebook 中你可以在每个关键节点用adata.write()保存结果发现问题时用sc.read_h5ad()快速恢复。数据和代码在同一个界面中交替出现这种体验是脚本编辑器很难带来的。3. Jupyter Notebook 核心概念与基础操作3.1 Jupyter Notebook 和 JupyterLab 到底有什么区别很多初学者会在这两个名字之间纠结。简单说JupyterLab 是 Jupyter Notebook 的下一代交互界面。但这不代表你必须迁移到 JupyterLab。两者的关系用一张表可以看得很清楚对比维度Jupyter NotebookJupyterLab界面风格单文档界面一个 Notebook 占据主区域多文档工作台可同时打开 Notebook、终端、文本编辑器文件管理功能较简单能浏览文件操作有限完整文件浏览器支持拖拽、多标签页、分栏布局扩展能力支持 extensions但生态相对简单插件体系更强大支持自定义布局上手难度更简单适合初学者稍复杂但功能上限更高运行内核一致底层都是 Jupyter Kernel一致从实际使用角度看如果你只是跑 Scanpy 分析两者功能差异不大。我的建议是下载 Anaconda 后自带的是经典 Notebook 界面可以先从这里开始。当你觉得需要在同一个浏览器页面里同时查看代码、终端和文档时再切换 JupyterLab 也不迟。不要在环境配置上过度纠结核心是跑通分析流程。3.2 Notebook 的 Cell 运行机制Jupyter Notebook 的基本单元是 Cell主要有两种类型Code Cell 和 Markdown Cell。Code Cell 用来写 Python 代码运行后会把输出显示在 Cell 下方。这里有一个非常重要的机制Cell 之间共享同一个内核Kernel。也就是说你在第一个 Cell 里定义了一个变量后面的 Cell 里可以直接使用它。这种全局命名空间的设计既方便又危险。方便在于你可以把步骤拆开危险在于如果你不按顺序运行 Cell或者修改了前面的 Cell 没有重新运行后续结果可能基于旧的变量状态。Markdown Cell 用来写说明文字支持 Markdown 语法也可以插入 LaTeX 数学公式。在单细胞分析中强烈建议在每一步分析前用 Markdown Cell 记录你的判断依据。比如“这里选择过滤 200 个基因以下的细胞是因为根据 violin plot这批细胞的基因数分布最低点在 200 附近”。这种记录对后续复现和论文方法部分写作非常有价值。3.3 Kernel 的作用与重启Kernel 是 Notebook 背后的 Python 解释器进程。当你点击运行按钮时代码被发送到 Kernel 执行。理解 Kernel 至少帮到你三个场景第一当变量状态混乱时你可以通过“Kernel → Restart Run All”把内核重启按顺序重新执行所有 Cell。这一步能解决大量“为什么这个变量不存在”的问题。第二安装新包后如果 Notebook 中import报错 ModuleNotFoundError通常需要重启 Kernel 才能加载新安装的包。第三当你打开一个旧 Notebook 文件时如果使用的是 PyCharm 或 VS Code 的 Notebook 支持也要注意选择正确的 Kernel 环境否则会因为 Python 解释器不一致而出现找不到包的问题。3.4 Notebook 文件格式 .ipynbNotebook 文件的后缀是.ipynb本质是一个 JSON 文件。这个格式的好处是方便 Git 版本控制和平台迁移坏处是如果文件较大打开会变慢如果有大量输出图像文件体积可能膨胀到几十 MB。建议在分析中定期清理输出Cell → Current Outputs → Clear保存比较干净的版本到 Git 仓库。对于数据文件如h5ad不要放进 Git而是使用独立的数据存储路径。4. Jupyter Notebook 环境搭建与常见问题4.1 通过 Anaconda 安装 Jupyter Notebook对于绝大多数单细胞数据分析场景推荐使用 Anaconda。Anaconda 不仅包含 Jupyter Notebook还预装了 NumPy、SciPy、pandas、matplotlib 等科学计算核心库能省去很多依赖问题。安装完成后Windows 用户可以在开始菜单找到Anaconda Prompt打开后执行jupyter notebook运行后终端会输出类似这样的信息[I 2024-01-01 10:00:00.123] Serving notebooks from local directory: C:\Users\... [I 2024-01-01 10:00:00.456] Jupyter Server is running at: http://localhost:8888/tree?tokenabcdef...默认情况下Jupyter 会在http://localhost:8888启动并自动打开默认浏览器。4.2 创建独立的 Conda 环境我要特别强调一个工程实践不要直接在 base 环境里安装 Scanpy。单细胞分析涉及大量依赖包版本冲突概率很高。推荐为每个项目创建独立环境conda create -n scanpy python3.9 conda activate scanpy pip install jupyter notebook pip install scanpy python -m ipykernel install --user --name scanpy --display-name Python (scanpy)注意第四条命令的作用把当前 conda 环境注册为 Jupyter 可用的 Kernel。如果你跳过这一步即使在终端里激活了scanpy环境在 Notebook 里新建文件时仍然只能选择默认的 Python 环境无法import scanpy。4.3 在 PyCharm 中使用 Jupyter NotebookPyCharm 专业版原生支持 Jupyter Notebook社区版也可以使用。如果你使用的是专业版最直接的方式是用 PyCharm 打开.ipynb文件PyCharm 会调用它内置的 Notebook 编辑器。在编辑器的右上角可以选择 Kernel选择你在第 4.2 步注册的scanpy环境即可。如果使用的是 PyCharm 社区版或者你的项目不是以.ipynb文件为核心可以换个思路在 PyCharm 的 Terminal 里启动 Jupyter Notebook然后通过浏览器访问localhost:8888照样能打开 Notebook。这样相当于把 PyCharm 当作终端和代码编辑器把 Jupyter 当作分析界面二者互补。4.4 Windows 下 Jupyter Notebook 打开后空白的排查这是一个非常高频的问题值得单独写一节。如果你在 Windows 上运行jupyter notebook后浏览器打开页面完全空白请按以下顺序排查。第一步看浏览器控制台。按 F12 打开开发者工具切到 Console 标签页如果有红色报错大多是 JavaScript 资源加载失败。第二步更换浏览器测试。很多情况下是当前浏览器与 Jupyter 前端不兼容或者浏览器缓存了旧的静态资源。换到 Edge、Chrome、Firefox 任一浏览器尝试通常能定位问题。第三步清空浏览器缓存和 Cookie特别是localhost:8888相关的缓存。第四步检查端口冲突。如果8888端口被其他程序占用Jupyter 会自动更换端口这时终端里显示的 URL 会变化。你要使用终端输出的最新 URL而不是手动输入的旧地址。第五步检查是否存在代理或网络加速软件干扰本地请求。这种情况在 Windows 上并不少见关闭代理工具后重试即可。如果以上都没解决可以在终端中强制指定浏览器打开 Jupyter命令如下。# 在 Jupyter 配置中指定浏览器Windows 系统 jupyter notebook --no-browser然后手动复制终端中显示的完整地址包含 token 的那一长串到 Chrome 或 Edge 中打开。4.5 如何更换 Jupyter Notebook 的默认浏览器有一些读者希望 Jupyter 不要自动打开旧版 IE 或某个不常用的浏览器。可以通过修改 Jupyter 配置文件来解决。先生成配置文件jupyter notebook --generate-config然后打开生成的jupyter_notebook_config.py找到类似# c.NotebookApp.browser的位置设置为你的目标浏览器路径。以 Chrome 为例在 Windows 下可以这样改写import webbrowser webbrowser.register(chrome, None, webbrowser.GenericBrowser(C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe)) c.NotebookApp.browser chrome修改后保存重新启动jupyter notebook就会自动用 Chrome 打开。5. Scanpy 核心概念从数据格式到分析流程5.1 AnnData理解 Scanpy 的基石Scanpy 的所有分析都围绕一个核心数据结构AnnData。这个名字是“Annotated Data”的缩写。理解 AnnData 的设计思路就理解了 Scanpy 的设计思路。AnnData 可以理解为一条数据总线上挂载了多个组件。它的核心字段包括字段作用类比X表达矩阵行为细胞列为基因一张行×列的数字表格obs细胞observation的元信息如样本来源、批次、细胞类型注释每一行细胞的“身份证”var基因variable的元信息如基因名、是否高变基因每一列基因的“说明书”obsm细胞的降维坐标如 PCA、UMAP 结果细胞的“投影坐标”varm基因的降维坐标如基因在 PCA 上的载荷基因的“投影坐标”uns非结构化元数据如参数记录、颜色设置备注信息在实际编码中你最常见的操作模式是先读取数据得到adata然后用adata.obs访问细胞信息用adata.var访问基因信息用adata.obsm[X_pca]访问降维结果。分析过程中产生的每一步新结果都会被挂载到adata上。这种设计让中间结果不会丢失也不需要在多个变量之间手动传递数据。5.2 Scanpy 标准分析流程说明书从数据到生物学发现Scanpy 的标准流程可以概括为七个步骤。这里先给一个宏观视图后面用代码具体实现。第一步数据读取与质量控制。读取表达矩阵计算每个细胞的基因数和线粒体基因比例根据阈值过滤低质量细胞和低表达基因。第二步归一化与对数化。消除测序深度差异使细胞间可比。第三步高变基因筛选。找出在细胞间表达差异最显著的基因减少后续计算量。第四步PCA 降维。将高维表达矩阵压缩到数十个主成分。第五步邻里图构建与 UMAP/tSNE 降维。基于 PCA 结果构建细胞之间的邻居关系再用 UMAP 可视化为二维平面。第六步聚类。使用 Leiden 算法识别细胞群。第七步marker 基因与细胞类型注释。对每个 cluster 做差异表达分析找到特征基因根据已知 marker 基因判断细胞类型。5.3 Scanpy 与 Seurat 的核心差异对于从 R 生态转过来的读者这里有必要做一个对比。Seurat 是 R 语言里最主流的单细胞分析包Scanpy 是 Python 生态的对应物。两者在分析思路上非常相似因为底层都是相同的统计学方法。但差异在于第一Scanpy 可以无缝衔接 Python 的深度学习生态。如果你想用 scVI、scANVI 等深度学习模型做批次校正或数据整合Python 生态中可以直接调用。而在 R 中整合这些模型往往需要经过中间格式转换。第二Scanpy 的可扩展性更好。对于数百万细胞级别的超大数据集Scanpy 支持基于anndata的分块处理可以配合scanpy.external中的工具处理大型数据。第三Seurat 在 R 社区中拥有更多现成的可视化修饰包而 Scanpy 的绘图风格更简洁定制需要手动改 matplotlib 参数。这不代表 Scanpy 比 Seurat 好或者差。更合理的判断是如果你想在 Python 生态中做单细胞分析或者需要后续接深度学习模型Scanpy 是绕不开的选择。6. Scanpy 完整分析流程示例下面进入核心实操部分。我会使用 Scanpy 内置的 PBMC 3K 数据集来演示完整流程。这个数据集来自 10x Genomics包含约 2700 个外周血单核细胞是 Scanpy 文档中的经典示例数据。6.1 环境准备与数据读取进入 Jupyter Notebook新建一个 Python 文件先导入必要的库。import numpy as np import pandas as pd import scanpy as sc import matplotlib.pyplot as plt # 设置画图参数让图像在 Notebook 中清晰显示 sc.settings.set_figure_params(dpi100, frameonFalse, figsize(5, 5)) sc.settings.verbosity 3 # 输出详细日志然后读取 PBMC 3K 数据。如果没有联网也可以使用sc.datasets.pbmc68k_reduced()读取一个更小的测试数据。adata sc.datasets.pbmc3k() print(adata)输出的类型信息AnnData object with n_obs × n_vars 2700 × 32738 var: gene_symbols这说明数据包含 2700 个细胞、32738 个基因。6.2 质量控制与过滤单细胞数据质量控制非常关键直接决定下游分析质量。我们计算三个核心指标每个细胞表达的基因数、每个细胞的总计数UMI 数、线粒体基因比例。这里需要解释一下线粒体基因比例高通常意味着细胞状态不佳可能是细胞破裂导致线粒体 RNA 泄漏也可能是凋亡信号。PBMC 数据中我们使用人类线粒体基因前缀MT-。# 计算线粒体基因比例 adata.var[mt] adata.var_names.str.startswith(MT-) sc.pp.calculate_qc_metrics(adata, qc_vars[mt], percent_topNone, log1pFalse, inplaceTrue)此时adata.obs中新增了n_genes_by_counts、total_counts、pct_counts_mt等列。我们先用小提琴图查看分布。sc.pl.violin(adata, [n_genes_by_counts, total_counts, pct_counts_mt], multi_panelTrue)根据常见经验PBMC 数据通常过滤掉基因数少于 200 的细胞基因数大于 2500 的细胞可能是双细胞线粒体基因比例高于 5% 的细胞可能是低质量细胞。但不同实验数据阈值会变化需要结合 violin plot 调整。sc.pp.filter_cells(adata, min_genes200) sc.pp.filter_cells(adata, max_genes2500) adata adata[adata.obs.pct_counts_mt 5, :]这里还有一个容易被忽略的步骤过滤基因。几乎所有细胞都不表达的基因没有分析价值反而增加计算量。sc.pp.filter_genes(adata, min_cells3)执行后可以打印数据形状确认过滤效果。print(adata)6.3 归一化、对数化与高变基因质控后需要进行数据标准化消除测序深度差异。sc.pp.normalize_total(adata, target_sum1e4) sc.pp.log1p(adata)normalize_total将每个细胞的总计数归一化到target_sumlog1p对数据做log(x1)变换使数据分布更接近高斯分布满足后续统计方法的假设。接下来筛选高变基因。这里需要理解它的意义单细胞数据有数万个基因但大部分基因在不同细胞间表达差异不大。高变基因筛选能保留信息量最大的基因显著降低后续 PCA 和聚类计算量。sc.pp.highly_variable_genes(adata, min_mean0.0125, max_mean3, min_disp0.5) sc.pl.highly_variable_genes(adata)然后把表达矩阵精简为只保留高变基因。注意这不是简单切掉数据而是把非高变基因保留下来的做法只是后续 PCA 只用高变基因。adata.raw adata adata adata[:, adata.var.highly_variable]这里有一个细节值得注意adata.raw adata保存了原始全部基因的表达矩阵供后续 marker gene 可视化使用。6.4 PCA 降维PCA主成分分析可以把高维的基因表达空间压缩为少数几个主成分。在 Scanpy 中只需要一行代码sc.tl.pca(adata, svd_solverarpack) sc.pl.pca_variance_ratio(adata, n_pcs50)pca_variance_ratio图展示了每个主成分解释的方差比例。通常选择曲线拐点处的主成分数但也常见直接取前 20 或前 30 个。对于 PBMC 3K前 15 到 20 个主成分通常足够。6.5 邻里图构建与 UMAP 可视化单细胞聚类的核心在于构建细胞之间的相似性网络。先基于 PCA 结果计算细胞的 k 近邻图然后用 Leiden 算法找聚类。sc.pp.neighbors(adata, n_neighbors10, n_pcs15) sc.tl.umap(adata) sc.pl.umap(adata, colorleiden)先运行聚类因为 UMAP 上色需要聚类标签。完整代码是sc.tl.leiden(adata, resolution0.5) sc.pl.umap(adata, color[leiden])这里resolution控制聚类数量。分辨率越低聚成的类越少分辨率越高聚成的类越多。PBMC 数据一般取0.5到1.0之间需要根据 UMAP 图上 cluster 的分离程度调整。6.6 聚类与 marker 基因分析聚类完成后每个细胞都被分配了一个 cluster 标签存在adata.obs[leiden]中。接下来要对每个 cluster 做差异表达分析找到 marker 基因。sc.tl.rank_genes_groups(adata, leiden, methodwilcoxon) sc.pl.rank_genes_groups(adata, n_genes20, shareyFalse)然后用sc.tl.marker_gene_overlap或查文献确定每个 cluster 的细胞类型。PBMC 数据常见的 cell type 有 T 细胞CD3D、B 细胞MS4A1、NK 细胞NKG7、单核细胞LYZ等。可以通过sc.pl.dotplot来验证。marker_genes { T cell: [CD3D, CD3E], B cell: [MS4A1, CD79A], NK cell: [NKG7, GNLY], Monocyte: [LYZ, CD14], } sc.pl.dotplot(adata, marker_genes, groupbyleiden)根据 marker 基因的表达模式可以把 cluster 重命名并赋值给adata.obs[cell_type]然后重新在 UMAP 上可视化。6.7 保存与读取分析结果分析结束时及时保存结果。adata.write(pbmc3k_analysis.h5ad)以后可以随时读取adata_read sc.read_h5ad(pbmc3k_analysis.h5ad)7. 运行结果与效果验证7.1 怎么判断你的分析“跑通了”很多初学者以为代码不报错就是分析完成这是误解。跑通的标准应该是每个关键输出都符合数据本身的生物学特征。判断质控是否合理要看过滤后的细胞数是否在合理范围。如果过滤后细胞数不足原来的 50%说明阈值可能过严需要回到 violin plot 重新观察分布。判断降维效果要看 UMAP 图上是否有明显的分离结构而不是一团颜色混杂的散点。判断聚类效果要看 cluster 数量是否过多或过少正常 PBMC 数据通常在 5 到 13 个 cluster 之间。7.2 预期输出示例当你依次运行第 6 节的代码预期会看到sc.pl.violin输出三张小提琴图展示质控指标分布过滤后曲线右移。sc.pl.highly_variable_genes输出一张散点图高变基因高亮显示。sc.pl.pca_variance_ratio输出方差贡献率曲线前 20 个主成分占比逐步下降。sc.pl.umap输出 UMAP 图不同 cluster 以不同颜色区分图上有清晰的细胞群聚团。sc.pl.rank_genes_groups输出每个 cluster 的 top 基因列表可用于确定细胞类型。7.3 失败后第一步看哪里运行失败时先看错误信息最后一行找到是哪个函数出的问题。常见错误有三类第一ModuleNotFoundError。这说明缺少依赖包或者你启动的 Kernel 与安装包的环境不一致。解决方式是检查 Kernel 选择然后在正确的环境中pip install。第二MemoryError。单细胞数据较大时常见解决方式是减少参与计算的基因数或换用更大内存的机器。第三ValueError通常是因为输入数据维度不符合函数要求。例如在未运行sc.pp.neighbors前调用sc.tl.umap会报找不到邻里图。8. Scanpy 与 Jupyter Notebook 常见问题排查问题现象可能原因排查方式解决方案Jupyter Notebook 打开页面空白浏览器缓存、代理、静态资源加载失败打开 F12 查看 Console 报错换 Chrome/Edge 测试关闭代理清缓存强制指定浏览器启动使用带 token 的完整 URLNotebook 中 import scanpy 报错Kernel 环境与安装环境不一致运行!which python查看解释器路径检查 Kernel 列表在正确 conda 环境注册 ipykernel或重新选择 KernelScanpy 运行报ValueError上游步骤未执行或数据过滤后维度异常逐 Cell 按顺序运行使用adata打印确认形状用Kernel → Restart Run All按顺序重跑聚类结果明显不合理主成分数选择不当或过滤阈值不准确查看 PCA 方差贡献率图检查过滤前后细胞数调整n_pcs参数回到 QC 步骤重新调阈值UMAP 图上所有点挤在一起邻居数过小或没有正确执行 PCA 和 neighbors检查 PCA 是否成功查看n_neighbors设置适当增大n_neighbors确保使用高变基因做 PCA保存的 h5ad 文件过大保存了过多中间结果和原始矩阵检查adata.uns与adata.raw大小清理不必要字段用adata adata[:, adata.var.highly_variable]瘦身后保存或删除uns中的冗余信息9. 最佳实践与工程建议9.1 Notebook 分析代码的组织规范把分析过程分成逻辑清晰的 Cell顺序执行不要随意跳转。建议格式如下Cell 1导入库与全局设置。Cell 2定义文件路径和参数常量。Cell 3读取数据与初步查看。Cell 4质控指标计算与可视化。Cell 5过滤。Cell 6归一化、对数化、高变基因。Cell 7PCA。Cell 8邻里图、UMAP、聚类。Cell 9marker 基因与注释。Cell 10保存结果。每一个关键决策点用 Markdown Cell 写明理由。如果你要在论文中报告分析流程这部分文字可以直接修改为方法部分的内容。9.2 依赖管理和可复现性强烈建议在项目目录中维护requirements.txt或environment.yml。当你完成分析将环境导出pip freeze requirements.txt或者用 conda 导出conda env export environment.yml这样同事或未来的你自己可以一键重建分析环境避免出现“换台电脑跑不了”的问题。9.3 数据管理与版本控制不要将.h5ad数据文件提交到 Git 仓库。建议的结构是project/ ├── data/ # 原始数据和中间数据不进 Git ├── notebook/ # .ipynb 文件进 Git ├── scripts/ # 可复用的 .py 工具函数 ├── results/ # 输出图表和表格 └── environment.yml # 环境锁文件9.4 谨慎使用inplaceTrue参数Scanpy 的很多函数提供了inplaceTrue参数默认在原对象上直接修改。这在 Notebook 分析中很便捷但要注意一旦执行了覆盖式修改再想回到上一步可能要重新从磁盘读取数据。建议在修改数据的步骤上先复制一份对象或者保留原始数据为raw。9.5 调参与记录的平衡单细胞分析允许反复调参数但不要只调不记。每改一个关键参数建议在 Markdown Cell 里记录为何要这样改以及前后效果差异。很多分析报告最终写不出来不是因为数据不好而是因为中间过程没有记录。10. 总结与后续学习方向这篇内容从 Jupyter Notebook 的运行机制讲到 Scanpy 的完整单细胞分析流程核心是想帮助你建立一套统一的分析框架用 Notebook 承载探索性分析用 Scanpy 完成科学计算用规范的文件组织保证可复现。如果你刚入门建议先把环境搭好用 PBMC 3K 数据完整跑通上面的代码对每一步的输出有一个直观印象。不要急着在自己的 10x 数据上跑完整流程因为不同数据集的质控特征差异很大没有经验时容易把下游分析带偏。接下来值得深入的方向有几个批次效应校正Harmony、scVI、细胞类型自动注释SingleR、CellTypist 或基于 marker 数据库的注释工具、轨迹分析用于发育相关研究、以及多组学数据整合。这些方向都建立在今天这套基础流程之上把基础打牢后再逐步扩展。最后给一个比较实用的建议把第 6 节的代码整理成一个模板 notebook连同常用的 QC 阈值、marker 基因列表一起保存在本地。每次拿到新数据先在这个模板上跑一遍再根据数据特征调整细节。这是把“会跑教程”变成“会分析真实数据”最有效的一步。
返回列表