news 2026/8/31 11:21:15

Jupyter Notebook+Scanpy搭建单细胞分析工作台:从环境配置到UMAP可视化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jupyter Notebook+Scanpy搭建单细胞分析工作台:从环境配置到UMAP可视化

如果你做生物信息学、单细胞转录组分析,有一个场景一定不陌生:拿到了表达矩阵,准备开始跑 Seurat 或 Scanpy,结果第一步环境就装了整整一个下午。更常见的情况是,教程里的代码你在终端里复制粘贴,跑完却看不到任何可视化结果,因为聚类图根本没弹出来,或者报了十几个版本冲突的错误。

这篇文章想讨论的,不只是“Jupyter Notebook 怎么用”,也不是“Scanpy 的 API 有哪些”。我想回答一个更实际的问题:如何把 Jupyter Notebook 和 Scanpy 组合起来,搭出一套适合自己的单细胞分析工作台。我相信,对多数做数据分析的人来说,Jupyter Notebook 不只是一个写代码的网页工具,它更是一种调试思维和可视化节奏的载体。而 Scanpy 代表的是 Python 生态里一整套单细胞分析范式。两者搭配,能让你从读数据、质控、标准化、聚类到可视化,全流程都在同一个界面里完成。

这篇文章会按真实使用顺序展开。先讲 Jupyter Notebook 和 Jupyter Lab 怎么选、Anaconda 环境怎么装、Scanpy 怎么安装;再讲 Jupyter Notebook 的常用操作和容易踩的坑;然后进入 Scanpy 核心数据结构 AnnData;最后给出一个完整可跑的 Scanpy 示例,从 pbmc3k 测试数据开始,到 UMAP 可视化和 marker 基因识别结束。每个阶段我都会给代码、给判断、给排查思路。

你在阅读过程中可以顺手打开终端跟着操作。不要只看不跑,这类工具文章最大的价值在于你把命令完整敲过一遍之后,形成的手感和肌肉记忆。

1. 为什么是 Jupyter Notebook 加 Scanpy

先聊一个最基本的判断。很多人第一次接触单细胞分析,会先在 R 语言里用 Seurat,后来转到 Python 这边时会问:我为什么要用 Scanpy?Jupyter Notebook 不就是个网页版的笔记本吗?

我的看法是,Scanpy 的价值并不只是“又多了一个 Python 包”,而在于它把单细胞分析流程结构化成了可复现、可扩展的 Pipeline。它的数据对象 AnnData 会把表达矩阵、细胞元信息、基因元信息和降维结果统一收纳。这种数据结构设计非常符合交互式分析的习惯:你每一步操作都在往同一个对象上叠加结果,不用频繁地维护多个 DataFrame,也不用手动保存中间文件。

而 Jupyter Notebook 恰好提供了这种交互式分析的最佳载体。它支持代码和 Markdown 混排,你可以一边写分析逻辑,一边记录思考;可以分 Cell 运行,把耗时步骤独立出来;还可以在同一个页面里渲染 UMAP、热图、小提琴图。相比直接在终端里跑 Python 脚本,Jupyter Notebook 更接近“分析过程的白板”,你可以随时回退、修改、重新执行某个 Cell。

需要注意一个边界:Jupyter Notebook 并不是万能的。它适合探索性分析、流程原型验证和技术分享,但如果你要做大规模自动化批量分析,或者要部署到生产环境,更合适的方式是把核心逻辑写成 Python 模块或脚本,再配合流程管理工具执行。这个边界理解清楚了,你才不会把 Jupyter Notebook 用成一把不合适的锤子。

2. Jupyter Notebook 的核心概念与适用场景

2.1 Notebook 是什么

Jupyter Notebook 是一个基于 Web 的交互式计算环境,核心单位是 Cell。一个 Cell 可以是一段 Python 代码,也可以是 Markdown 文本。代码 Cell 可以单独执行并保留变量状态,Markdown Cell 用来写说明和结论。Notebook 文件以.ipynb格式保存,里面包含代码、输出、富文本展示和元数据。

这种“代码 + 输出 + 文档”合一的格式,特别适合做数据分析。因为它天然保留了执行顺序和结果,你可以随时复盘:某一列数据在哪个步骤被过滤了,某个聚类结果是在什么参数下得到的,图表对应的代码是哪一段。对单细胞分析这种步骤多、参数多的任务来说,这种可追溯性非常重要。

2.2 Jupyter Notebook 与 Jupyter Lab 的区别

很多新手会纠结到底装哪个。这里给你一个明确的结论:如果你二选一,优先考虑 Jupyter Lab,但不要因此忽略 Notebook。Jupyter Lab 是 Jupyter 项目的下一代界面,它把 Notebook、终端、文件管理器、文本编辑器集成到了同一个界面中。简单说,Jupyter Lab 是“集成开发环境”,而 Jupyter Notebook 是“单文档笔记本”。

如果你的工作流是单细胞分析,你经常需要在笔记本、终端和图像窗口之间切换。Jupyter Lab 的多标签布局会更顺手。你可以左侧开一个 Notebook,右侧跑一个终端,上方还能拖一个图像窗口,不用来回切浏览器标签。但如果你只是快速查看一个已有的 Notebook 文件,或者只是想跑一个简短的分析流程,Jupyter Notebook 的简洁界面依然够用。

一个重要提醒是,很多教程在讲“Jupyter Notebook 安装”时,实际上默认安装的是 Jupyter Lab。这不是错误,因为jupyter notebook命令在很多环境里依然可用。你需要知道自己用的到底是哪个界面,否则在看菜单、找按钮时会觉得和教程对不上。

2.3 Notebook 适合哪些场景

  • 单细胞数据的探索性分析:读入数据、过滤、标准化、聚类、可视化。
  • 数据清洗和特征工程的流程原型。
  • 机器学习模型的快速试错和小样本训练。
  • 教学和分享:代码、输出、图表和解释放在一起,读者可以逐段理解。
  • 分析报告生成:执行完成后可以导出为 HTML 或 PDF。

注意,Notebook 不适合作为生产调度的载体。如果你有每天自动跑的一次性分析任务,应该把核心逻辑抽成.py脚本,再用调度工具执行。Notebook 适合人机交互,脚本适合无人值守。

3. 环境准备与安装

环境准备这一步是很多新手卡住的地方。我建议按照“Anaconda → 虚拟环境 → Jupyter → Scanpy”的顺序来,不要直接在 base 环境里安装一堆包。

3.1 安装 Anaconda

Anaconda 是一个 Python 发行版,自带 conda 包管理器和大量常用科学计算包。它解决了两个痛点:Python 环境隔离和底层依赖管理。对生物信息学分析来说,很多包依赖特定版本的 numpy、scipy,直接用 pip 安装容易冲突,conda 则能从通道层面处理这些依赖。

安装方式比较简单,可以去 Anaconda 官网下载对应系统的安装包。安装完成后,打开终端检查:

conda --version python --version

如果显示 conda 版本号和 Python 版本,说明安装成功。这里提醒一下,安装 Anaconda 的过程中,安装器默认会执行conda init,修改 shell 配置文件。如果你不想让 conda 自动激活 base 环境,可以执行:

conda config --set auto_activate_base false

这样每次打开终端不会自动进入 base 环境,虚拟环境管理会更清爽。

3.2 创建并激活虚拟环境

强烈建议为单细胞分析单独建一个环境,不要直接在 base 环境里安装 scanpy。原因是 scanpy 依赖的包版本很多,和 base 环境里已有的包可能冲突。单独建环境可以让你随意升级、回滚,不会搞坏其他项目。

conda create -n scanpy_env python=3.9 -y conda activate scanpy_env

创建后,你的终端提示符前面会出现(scanpy_env),说明当前处于该虚拟环境中。

3.3 安装 Jupyter Notebook

在虚拟环境中安装 Jupyter:

conda install jupyter -y

这条命令会安装 Jupyter Notebook 和 Jupyter Lab。如果你只需要 Notebook,也可以:

conda install notebook -y

安装完成后,在虚拟环境里启动:

jupyter notebook

如果一切正常,终端会输出一段以http://localhost:8888开头的 URL,然后浏览器会自动打开 Notebook 界面。

这里有个常见误区:你在某个环境里安装了 jupyter,但这个环境里的 jupyter 命令可能和你系统全局的 jupyter 不是同一个。如果在启动时报错找不到命令,用下面命令确认是否在当前环境:

which jupyter

在 scanpy_env 环境中,应该显示该环境下的路径。

3.4 安装 Scanpy

Scanpy 是一个基于 Python 的单细胞分析框架,官方推荐通过 conda 或 pip 安装。在 scanpy_env 环境中执行:

conda install -c conda-forge scanpy -y

也可以使用 pip:

pip install scanpy

两种方式都可行。conda-forge 渠道在依赖解析方面更严格,pip 方式更直接。如果你同时使用 R 生态和 Python 生态,并且后续可能在同一个环境里安装其他生物信息学工具,conda 方式通常更省心。安装完成后,验证:

python -c "import scanpy as sc; print(sc.__version__)"

能输出版本号说明安装成功。注意不要纠结于具体版本号,Scanpy 在不断更新,本文示例基于主流稳定版本,API 基本兼容。

3.5 PyCharm 中的 Jupyter Notebook

如果你习惯使用 PyCharm,有两种方式启动 Jupyter Notebook。

第一种,在 PyCharm 的 Terminal 面板中运行jupyter notebook,会在你当前项目目录下启动服务。此时 PyCharm 的 Terminal 和你操作系统终端的区别只是界面集成,命令行为一致。

第二种,PyCharm Professional 版本支持直接打开.ipynb文件,并在 Python 解释器中配置 Jupyter 服务器。如果你是 Community 版本,没有直接打开 Notebook 的功能,更推荐使用方式一或者直接使用 Jupyter Lab。

需要留意的是,PyCharm 中如果要用自定义 conda 环境,需要在 Settings 里把 Python Interpreter 指向对应环境。否则你打开 Notebook 后创建的 Kernel 会使用错误环境,导致 import scanpy 失败。

4. Jupyter Notebook 基础操作与常用技巧

4.1 新建 Notebook 与界面认识

打开 Jupyter Notebook 后,你会看到文件列表。点击右侧的 “New” 下拉菜单,选择 “Python 3” 即可新建笔记本。

界面顶部是菜单栏和工具按钮,主要区域是 Cell。每个 Cell 都有一个输入框和输出区域。代码 Cell 写的 Python 代码,执行后结果会直接显示在输出区域。Markdown Cell 显示渲染后的文本。

新建 Notebook 后,建议第一时间把文件保存为有意义的名字,比如pbmc3k_scanpy_analysis.ipynb。这比默认的Untitled.ipynb好一万倍。

4.2 核心快捷键

  • Shift + Enter:运行当前 Cell 并移动到下一个 Cell。
  • Ctrl + Enter:运行当前 Cell,但不移动。
  • A:在当前 Cell 上方插入新 Cell。
  • B:在当前 Cell 下方插入新 Cell。
  • D D:连续按两次 D,删除当前 Cell。
  • M:把当前 Cell 切换为 Markdown。
  • Y:把当前 Cell 切换为 Code。
  • Esc:退出编辑模式。
  • Enter:进入编辑模式。

这些快捷键是日常使用最频繁的,建议练习到肌肉记忆。

4.3 魔法命令

Jupyter Notebook 支持 IPython 的魔法命令,它们以%开头,用来简化操作。

# 在 Notebook 中显示 matplotlib 图像 %matplotlib inline # 查看当前工作目录 %pwd # 列出当前目录文件 %ls # 运行一个 Python 脚本 %run myscript.py # 统计单行代码执行时间 %timeit sum(range(1000)) # 统计整个 Cell 执行时间 %%time import time time.sleep(1)

其中%matplotlib inline在做单细胞可视化时非常重要。没有这行命令,sc.pl.umap()产出的图在某些环境下可能不显示。不过要注意,在 Jupyter Lab 中,matplotlib 的渲染方式已经优化,有时不设置 inline 也能正常显示。但这行命令在 Notebook 中依然是稳妥选择。

4.4 Markdown 基本写法

Markdown Cell 支持标题、列表、链接、图片和 LaTeX 公式。写分析报告时,建议每个分析阶段都加一个 Markdown Cell,说明这一个步骤的目标和判断依据。

### 数据质控 本步骤过滤掉低质量细胞和低表达基因。 - 每个细胞至少表达 200 个基因 - 每个基因至少在 3 个细胞中表达

4.5 如何在其他浏览器中打开 Jupyter Notebook

默认情况下,Jupyter Notebook 会用系统默认浏览器打开。如果你想在指定浏览器中打开,有几种方式。

方式一:启动时使用--no-browser,不自动打开浏览器,然后手动复制 URL 到你想要的浏览器。

jupyter notebook --no-browser

启动后,终端会显示类似http://localhost:8888/?token=xxxxxxxx的 URL,你复制到 Chrome 或 Edge 中即可。

方式二:修改 Jupyter 配置文件的浏览器设置。

jupyter notebook --generate-config

这会生成~/.jupyter/jupyter_notebook_config.py,打开文件找到c.NotebookApp.browser配置项,取消注释并设置为你想要的浏览器启动命令。

c.NotebookApp.browser = r'C:\Program Files\Google\Chrome\Application\chrome.exe --new-window %s'

注意,Windows 路径中需要写成双反斜杠。设置完成后重启 Jupyter Notebook 即可生效。

方式三:如果你在服务器或远程主机上运行 Jupyter,需要把127.0.0.1:8888做端口转发。这里是合法运维场景下的常规操作,建议结合公司或云平台的网络策略实施。如果你只是为了本地分析,用方式一就够了。

5. Windows 下 Jupyter Notebook 打开后空白的排查思路

之前的热搜词里有一个很典型的问题:Windows 下 Jupyter Notebook 打开后空白。这个问题在网络搜索中的出现频率非常高,很多人在安装 Anaconda 后,双击打开 Jupyter Notebook,浏览器里却只有一个空白页。

这里先说结论:空白页面大多数情况下不是 Jupyter 本身坏了,而是浏览器端脚本加载或显示异常。排查顺序建议如下。

第一步,看终端输出。Jupyter 在启动时会在终端实时输出日志。如果终端里显示http://localhost:8888且没有任何报错,说明服务端正常。如果终端有红色报错,先看报错信息。

第二步,检查浏览器地址栏。如果地址是http://localhost:8888http://localhost:8888/tree,但页面空白,先尝试强制刷新页面,快捷键是Ctrl + Shift + R。有时候是浏览器缓存了旧的脚本,导致新版本加载失败。

第三步,换一个浏览器。曾经有用户反馈,某些安全策略严格的浏览器扩展会导致 Jupyter 页面空白。换成 Chrome 无痕模式或 Edge 试试。

第四步,检查环境。Jupyter 的依赖包版本如果出现冲突,也可能导致前端资源加载失败。此时可以在当前环境执行:

pip install --upgrade notebook

如果你用的是 conda,也可以:

conda update notebook -y

第五步,如果还是空白,考虑端口冲突或防火墙策略。8888端口如果被其他程序占用,Jupyter 会自动切换端口,在终端会看到http://localhost:8889之类的地址。确认你访问的是终端中显示的最新地址。

从排查经验来看,大多数空白问题集中在浏览器缓存和扩展插件上。不建议第一反应就重装 Anaconda,那会把问题扩大化。

6. Scanpy 的核心数据结构:AnnData

在写 Scanpy 代码之前,必须先理解 AnnData。它是 Scanpy 的数据容器,也是整个分析流程的“中枢”。

AnnData 有几个关键属性:

  • X:表达矩阵,通常是一个numpy.ndarrayscipy.sparse矩阵。行是细胞,列是基因,值表示表达量。
  • obs:细胞维度的元数据。每个细胞所属的样本、批次、测序深度、线粒体基因比例等信息都存在这里。
  • var:基因维度的元数据。基因名、基因类型、高变基因标记等信息存在这里。
  • obsm:细胞维度的降维结果,比如 PCA、UMAP、TSNE 的结果。
  • varm:基因维度的降维结果。
  • uns:自由存放分析过程中产生的非结构化信息,比如聚类颜色的映射、marker 基因结果。
  • layers:表达矩阵的多层表示,比如原始计数、标准化后的值、log 转换后的值。

用一个通俗的类比来理解:AnnData 像一个 Excel 工作簿。X是主表,obs是每个样本行的备注列,var是每个基因列的备注行,obsm是额外添加的“分析结果 Sheet”。一次 Scanpy 分析的本质,就是不断在 AnnData 上做操作,然后把结果写回对应属性。

因此你在分析时要养成习惯:每执行一个分析步骤,用print(adata)查看 AnnData 对象的变化。它会显示细胞数、基因数,以及已经被添加的 key 名称。这比记忆 API 更有效。

7. Scanpy 完整分析流程:从 pbmc3k 到 UMAP 与 marker 基因

这一节我们用一个公开测试数据集pbmc3k来走通全流程。这个数据集来自 10X Genomics,包含 2700 个外周血单核细胞,数据量小,适合教学演示。

7.1 加载数据

在 Jupyter Notebook 中新建一个 Cell,输入以下代码并执行:

import scanpy as sc # 设置图像显示优化,svg 格式放大不模糊 sc.settings.set_figure_params(dpi=100, facecolor='white') adata = sc.datasets.pbmc3k() print(adata)

执行后,你会看到 AnnData 对象的概要信息,包括细胞数和基因数。pbmc3k()函数会从 Scanpy 的示例数据源下载数据。如果网络受限,也可以把数据文件放到本地后用sc.read_10x_mtx()读取,我们稍后会讲。

7.2 数据质控

质控的目的是去掉“空液滴”和“多细胞液滴”。常用的标准是:每个细胞检测到的基因数、测序深度和线粒体基因比例。

import pandas as pd import numpy as np # 过滤低质量细胞:至少表达 200 个基因 sc.pp.filter_cells(adata, min_genes=200) # 过滤低表达基因:至少在 3 个细胞中表达 sc.pp.filter_genes(adata, min_cells=3) # 计算线粒体基因比例 adata.var['mt'] = adata.var_names.str.startswith('MT-') sc.pp.calculate_qc_metrics( adata, qc_vars=['mt'], percent_top=None, log1p=False, inplace=True ) # 过滤线粒体比例过高和基因数过多的细胞 sc.pp.filter_cells(adata, max_genes=5000) adata = adata[adata.obs.pct_counts_mt < 20, :].copy() print(f"质控后剩余细胞数: {adata.n_obs}")

这里adata.var['mt']是一个布尔向量,标记哪些基因是线粒体基因。注意,不同数据库中线粒体基因前缀不一样,人类是MT-,小鼠是mt-,如果分析小鼠数据,需要相应调整。

质控的逻辑并不复杂,但参数选择会影响后续分析结果。max_genes=5000pct_counts_mt < 20是常用的经验值,具体项目中应该结合数据的实际分布来调整。最好在质控前先画出分布图,再确定阈值。

7.3 标准化与高变基因

单细胞测序数据存在测序深度差异,需要标准化来消除这种技术因素。

# 总量标准化:每个细胞的总表达量归一化到 10000 sc.pp.normalize_total(adata, target_sum=1e4) # 对数转换 sc.pp.log1p(adata)

标准化之后,识别高变基因。这些基因在细胞间表达差异最大,用来做主成分分析更能代表细胞类型。

sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5) print(adata.var.head())

可视化高变基因的分布:

sc.pl.highly_variable_genes(adata)

这一步会输出高变基因筛选图,横轴是平均表达量,纵轴是离散度。全流程中你可以看到两张图,这比干看代码直观得多。

7.4 PCA 降维

在做 PCA 之前,通常先把数据限定到高变基因,并且保存一份标准化后的完整数据到raw,方便后续 marker 基因可视化时参考。

# 保存标准化后的完整数据 adata.raw = adata # 下一步分析用高变基因 adata = adata[:, adata.var.highly_variable] # PCA sc.tl.pca(adata, svd_solver='arpack') sc.pl.pca_variance_ratio(adata, n_pcs=50)

sc.pl.pca_variance_ratio会画出方差解释率曲线,用来决定后续邻居图使用多少个主成分。根据曲线拐点,通常选择 10 到 40 个主成分。

7.5 邻居图与 UMAP

PCA 之后,我们用主成分空间构建细胞之间的邻居关系,这是聚类和可视化共同的基础。

sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40) sc.tl.umap(adata) sc.pl.umap(adata, color='leiden')

这里会运行 UMAP 算法。UMAP 的随机性比较强,如果想让结果可复现,可以设置random_state

sc.tl.umap(adata, random_state=42)

在 Notebook 中,执行 UMAP 后,adata.obsm['X_umap']会被写入,这就是每个细胞的二维坐标。你可以用df = pd.DataFrame(adata.obsm['X_umap'], index=adata.obs_names)查看。

7.6 聚类

Scanpy 默认推荐使用 Leiden 算法进行聚类。Leiden 的核心参数是resolution,它控制聚类的“粗粒度”和“细粒度”。数值越大,得到的簇越多。

sc.tl.leiden(adata, resolution=0.5, random_state=42)

执行后,聚类结果会写入adata.obs['leiden']。重新绘制 UMAP,颜色按聚类着色:

sc.pl.umap(adata, color=['leiden'], legend_loc='on data')

legend_loc='on data'会把簇标签显示在对应聚类区上,方便直接观察。

7.7 识别 marker 基因

聚类之后,最重要的一个任务是找出每个 cluster 的 marker 基因。Scanpy 使用rank_genes_groups做差异表达分析。

sc.tl.rank_genes_groups(adata, 'leiden', method='wilcoxon', n_genes=20)

查看结果:

result = adata.uns['rank_genes_groups'] for cluster in result['names'].dtype.names: genes = list(result['names'][cluster][:10]) print(f"Cluster {cluster}: {genes}")

也可以用 Scanpy 内置的可视化函数绘制 marker 基因热图:

sc.pl.rank_genes_groups_heatmap(adata, n_genes=10, groupby='leiden')

这张热图非常直观,每一列是 cluster,每一行是 marker 基因。颜色越亮代表该基因在这个 cluster 中表达越高。

7.8 保存与导出

分析完成后,建议保存为.h5ad文件,这是 Scanpy 的标准格式,可以保留全部分析结果。

adata.write('pbmc3k_analysis.h5ad')

同时可以导出 UMAP 坐标和 marker 基因表格,方便后续用其他工具查看。

umap_df = pd.DataFrame( adata.obsm['X_umap'], index=adata.obs_names, columns=['UMAP1', 'UMAP2'] ) umap_df['leiden'] = adata.obs['leiden'].values umap_df.to_csv('pbmc3k_umap.csv')

8. 如何读取本地 10X 数据

scanpy.datasets.pbmc3k()适合学习演示,但在真实项目中,你面对的是filtered_feature_bc_matrix文件夹或.h5文件。Scanpy 提供了对应接口。

如果数据是 10X 的.h5格式:

adata = sc.read_10x_h5('filtered_feature_bc_matrix.h5') # 注意:如果数据来自多个样本,通常需要先合并再做分析 adata.var_names_make_unique()

如果数据是 10X 的 mtx 格式(文件夹中包含barcodes.tsv.gzgenes.tsv.gzmatrix.mtx.gz):

adata = sc.read_10x_mtx( 'filtered_feature_bc_matrix/', var_names='gene_symbols', make_unique=True )

var_names='gene_symbols'表示使用基因符号作为基因名,而不是 Ensembl ID。读取后建议先打印adataprint(adata.var.head()),确认基因名正确。

如果你有多个样本,需要合并。Scanpy 支持用concat合并:

import scanpy as sc import anndata as ad adata_list = [] for sample in ['sample1', 'sample2']: adata_tmp = sc.read_10x_h5(f'{sample}/filtered_feature_bc_matrix.h5') adata_tmp.obs['sample'] = sample adata_list.append(adata_tmp) adata = ad.concat(adata_list, join='outer', label='batch') adata.var_names_make_unique()

合并后别忘了做批次整合。批次效应是单细胞分析的大坑,如果不同样本存在明显批次差异,聚类结果可能被批次主导而不是生物差异。常用策略包括 Harmony、BBKNN 或 Scanorama。Scanpy 生态中,Harmony 可以通过sc.external.pp.harmony_integrate调用,不过需要额外安装。

9. 常见问题与快速排查

问题现象可能原因排查方式解决方案
Jupyter Notebook 启动后浏览器空白浏览器缓存或扩展插件冲突;notebook 前端资源加载失败强制刷新;换浏览器无痕模式;查看终端日志升级 notebook;更换浏览器;清理缓存
端口 8888 被占用已经有一个 Jupyter 服务在运行查看终端日志中的新端口访问终端提示的新 URL,或关闭旧进程
import scanpy报错 ModuleNotFoundError当前 Kernel 环境不是安装 scanpy 的环境执行which python;检查 Jupyter Kernel 列表把 Jupyter 的 Kernel 指向正确环境,或在正确环境重新安装 jupyter
sc.read_10x_h5读取后基因名为 Ensembl ID没有使用var_names参数查看adata.var.head()var_names='gene_symbols'重新读取
UMAP 结果每次运行都不一样UMAP 和 Leidan 有随机性没有设置随机种子设置random_state参数
质控后细胞数过多或过少过滤阈值不合理绘制分布图判断拐点调整min_genesmax_genespct_counts_mt
聚类个数太多或太少resolution 参数不合适尝试多个 resolution 值调小/调大 resolution,通常范围在 0.1 到 2.0 之间

这里要特别强调一个容易忽略的问题:Kernel 环境不一致。你可以在终端用pip install scanpy安装成功,但 Jupyter Notebook 使用的 Kernel 可能是另一个 Python 环境。打开 Notebook 后,在代码 Cell 里执行import sys; print(sys.executable),输出的路径应该是安装 scanpy 的虚拟环境路径。如果不是,说明 Kernel 配置错了。

修复方式是在正确环境中安装 ipykernel,并添加内核:

conda activate scanpy_env pip install ipykernel python -m ipykernel install --user --name scanpy_env --display-name "Python (scanpy_env)"

然后刷新 Jupyter Notebook 页面,在 Kernel 菜单里切换为 “Python (scanpy_env)”。

10. 最佳实践与工程建议

10.1 用 Markdown Cell 记录分析日志

单细胞分析是强探索性的工作,你会反复调整阈值和参数。建议在每个步骤之前用 Markdown Cell 说明当前分析的版本、数据和目标;在步骤之后记录结论。这不仅是给别人看的,更是给你自己看的。两周之后再打开 Notebook,你会庆幸当时记录了“为什么要把min_genes设为 200”。

10.2 保存中间结果

单细胞数据分析流程较长,有些步骤(比如聚类和 marker 基因分析)耗时久。建议在关键节点保存.h5ad文件。不过要注意,.h5ad文件会包含全部原始数据,体积较大,只适合作为中间结果保留。你需要理解并遵守当前实验室或分析环境关于数据存储和敏感数据的合规要求,不要随意把数据复制到未授权位置。

10.3 生产环境不要用 Notebook 跑全流程

Notebook 适合交互式探索,但正式批量跑数据时,建议把核心分析流程写成.py脚本,通过命令行参数传递输入输出路径。这样更利于日志记录、异常处理和定时调度。你可以把 Notebook 当作“开发草稿”,把脚本当作“正式交付物”。

10.4 理解数据,而不是盲目套参数

很多新手在质控时直接把阈值抄过来:min_genes=200max_genes=5000pct_counts_mt < 20。这些参数对 pbmc3k 有效,但换到肿瘤数据、空间转录组数据、不同测序平台的数据时,可能需要完全不同的阈值。我强烈建议每次过滤前都画出基因数、测序深度、线粒体比例的分布图,用数据说话。

10.5 多环境管理

在 conda 里为不同项目建不同环境是一个好习惯。比如scanpy_env专门做单细胞分析,ml_env专门做机器学习。多用conda env list查看环境,用conda env export > environment.yml导出环境依赖。这样换机器、换同事电脑时,几行命令就能恢复环境。

10.6 版本记录

在分析报告的末尾,加上一行版本信息:

import scanpy as sc import anndata as ad print(f"scanpy: {sc.__version__}") print(f"anndata: {ad.__version__}")

不要小看这行代码。几个月后如果结果需要复现,它是最直接的线索。

11. 总结与后续学习方向

这篇文章从 Jupyter Notebook 的安装和基础操作讲起,重点放在它与 Scanpy 组合使用时的完整工作流。你应该已经理解:Jupyter Notebook 是一种交互式分析载体,扫描分析的核心是理解 AnnData 的数据结构,而不是死记 API;Scanpy 的标准流程是数据加载、质控、标准化、高变基因选择、PCA、邻居图、UMAP、Leiden 聚类和 marker 基因分析。

如果你完整跑通了上面的 pbmc3k 示例,接下来可以沿着四个方向深入:

第一,换一份真实数据练习。到 10X Genomics 官网下载公开数据集,或者使用你的研究组数据,把 pbmc3k 的流程重新跑一遍。真实数据永远比教程数据复杂,你会遇到批次效应、稀疏矩阵、不同样本合并等问题。

第二,深入学习标注。Leiden 聚类得到的数字编号并没有生物学含义,你需要对照 marker 基因把它们标注成 T 细胞、B 细胞、NK 细胞等,这需要一定免疫学知识。后面我也计划专门写一篇基于 P 细胞类型自动注释的方法对比。

第三,学习批量整合。Harmony、BBKNN、Scanorama 这些工具解决的是同样问题:不同样本之间的批次效应。它们各有适用条件,理解它们的数学假设比会用 API 更重要。

第四,把工作流工程化。把 Notebook 迁移成.py脚本,学习 Snakemake 或 Nextflow 这类流程管理工具,能把你的分析从“自己跑通”提升到“可重复、可共享、可规模部署”。

最后提醒一句,单细胞分析的上限不在工具,而在实验设计和你对生物学问题的理解。Jupyter Notebook 和 Scanpy 能帮你把分析过程整理得井井有条,但一个清晰的研究问题,才是整个分析流程真正的起跑线。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 11:20:25

Grok Bot模板共享上线:团队协作与提示词工程实践指南

这次我们来看一个很实用的更新&#xff1a;Grok Bot 模板现在支持与他人共享了。如果你一直在用 Grok 做内容生成、知识库问答、客服助手这类 Bot 场景&#xff0c;应该知道模板的最大痛点就是“写好的配置只能自己用”。团队协作时&#xff0c;每个人都要重复配一遍系统提示词…

作者头像 李华
网站建设 2026/8/31 11:17:42

多厂商网络设备配置手册:交换机路由器防火墙命令实战与模拟器实验

这次我们来看一份覆盖华为、H3C、锐捷、思科等多厂商的网络设备配置手册合集。注意&#xff0c;不是只讲某个品牌的一两条命令&#xff0c;而是把交换机、路由器、防火墙的常用配置命令按场景整理好&#xff0c;能查、能练、能对着敲。这类手册最核心的价值不是“命令大全”四个…

作者头像 李华
网站建设 2026/8/31 11:12:53

心智世界模型:从预测物理到理解认知的下一代AI方向

如果你过去一年持续关注 AI 领域的进展&#xff0c;大概率会注意到两个高频词频繁出现在技术圈和投资圈&#xff1a;一个叫“世界模型”&#xff0c;一个叫“大模型”。很多人默认它们是一回事&#xff0c;甚至把 Sora 这类视频生成模型直接称之为“世界模型”&#xff0c;然后…

作者头像 李华
网站建设 2026/8/31 11:10:10

合成数据与后训练:VLM在智慧城市与农业机器人中的落地路径

最近大模型后训练、VLM 推理、合成数据这几个词频繁出现在一起。很多人手里已经有基础视觉语言模型&#xff0c;也能跑通微调&#xff0c;但一到真实项目就卡住。比如智慧城市项目里&#xff0c;监控图像中的夜晚小目标漏检严重&#xff0c;模型输出一会儿中文一会儿英文&#…

作者头像 李华
网站建设 2026/8/31 11:09:33

LLM Wiki实战:DeepSeek Harness构建工业级知识编译管线

很高兴能和你一起拆解“LLM Wiki”这个最近热度很高的方向。如果你关注过 Andrej Karpathy 提出的 LLM Wiki 范式&#xff0c;或正在寻找一套能把知识库、知识图谱和大模型问答结合起来落地的方案&#xff0c;那么这篇实战笔记会非常匹配你的需求。文章会从概念入手&#xff0c…

作者头像 李华
网站建设 2026/8/31 11:07:47

基于STM32的可见光通信系统设计与实现

简介&#xff1a;本资源是一套基于STM32平台的可见光通信&#xff08;VLC&#xff09;完整嵌入式开发实践方案&#xff0c;面向嵌入式开发者、物联网方向学生及光电通信初学者&#xff0c;解决可见光调制解码、LED驱动控制与光信号收发系统集成等核心问题。压缩包含817个文件&a…

作者头像 李华