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,浏览器自动打开 |
| 是否支持 API | Jupyter 提供 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 python=3.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文件,选择需要使用的 Kernel,PyCharm 会自动调用本机 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 --port=9999如果要允许局域网内其他机器访问,需要额外配置。这里不展开,因为默认绑定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.mtx+barcodes.tsv+features.tsv组合,以及.h5文件。
测试读取一个.h5ad文件:
import scanpy as sc # 设置图像风格 sc.settings.set_figure_params(dpi=100, facecolor="white") # 读取数据 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_names="gene_symbols", cache=True )注意,read_10x_mtx函数的路径应该指向包含matrix.mtx的文件夹,而不是直接指向文件本身。如果路径不对,会报错找不到文件。
5.5 数据质量控制与过滤
拿到 AnnData 对象后,第一个步骤通常是质控。Scanpy 里最基本的质控指标有三个:每个细胞的基因计数、每个细胞的总 UMI 计数、每个细胞的线粒体基因比例。
# 计算质量控制指标 sc.pp.calculate_qc_metrics(adata, qc_vars=["mt-"], percent_top=None, inplace=True)在人类数据中,线粒体基因通常以MT-开头。计算出指标后,可以用小提琴图观察分布:
sc.pl.violin(adata, keys=["n_genes_by_counts", "total_counts", "pct_counts_mt-"], multi_panel=True)看到图后,你需要根据分布情况设置过滤阈值。常见做法是保留基因数在 200 到 5000 之间、线粒体比例低于 20% 的细胞,但阈值需要根据具体数据调整。
sc.pp.filter_cells(adata, min_genes=200) sc.pp.filter_genes(adata, min_cells=3) # 线粒体比例过滤 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_sum=1e4) sc.pp.log1p(adata) # 2. 高变基因筛选 sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5) sc.pl.highly_variable_genes(adata) # 3. 数据标准化 sc.pp.scale(adata, max_value=10) # 4. PCA 降维 sc.tl.pca(adata, svd_solver="arpack") sc.pl.pca_variance_ratio(adata, n_pcs=50) # 5. 邻居图构建 sc.pp.neighbors(adata, n_neighbors=15, n_pcs=30) # 6. UMAP 降维 sc.tl.umap(adata) sc.pl.umap(adata, color="batch") # 7. 聚类 sc.tl.leiden(adata, resolution=0.5) sc.pl.umap(adata, color="leiden")每一步都有对应的输出:
sc.pl.highly_variable_genes输出高变基因散点图。sc.pl.pca_variance_ratio输出主成分方差占比图。sc.pl.umap输出 UMAP 降维图,每个点代表一个细胞。sc.pl.umap加color="leiden"显示聚类结果。
判断流程是否成功,最直观的标准就是 UMAP 图上是否出现有意义的细胞群。如果所有细胞挤成一团,可能原因是高变基因筛选参数不合适,或 PCA 维度选择太低。可以调大n_pcs或调整resolution参数。
5.7 标记基因分析
聚类完成后,可以计算每个簇的标记基因:
sc.tl.rank_genes_groups(adata, groupby="leiden", method="wilcoxon") sc.pl.rank_genes_groups(adata, n_genes=20, sharey=False)输出的热图和表格会告诉你每个簇高表达的基因是什么。结果保存为表格:
result = sc.get.rank_genes_groups_df(adata, group="0") result.to_csv("cluster0_markers.csv", index=False)这一步在实际数据分析中很有用,可以用来注释细胞类型。
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"], env=env, check=True )在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(f"Processing 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(f"CPU 使用率: {process.cpu_percent(interval=1):.1f}%")在运行 Scanpy 的sc.pp.neighbors或sc.tl.umap时,内存占用会有明显上升。尤其 UMAP 会重复多次近邻计算,数据量大时耗时较长。
7.2 哪些操作最耗资源
| 操作 | 资源消耗特点 | 优化建议 |
|---|---|---|
| 读取大文件 | 磁盘 I/O 和内存 | 先用read_10x_mtx的cache=True参数缓存 |
| 高变基因筛选 | CPU 计算 | 通常很快,不用过度优化 |
| 归一化 | 内存 | 不会特别大 |
| 邻居图构建 | CPU 和内存 | 设置合理的n_neighbors,不要盲目调大 |
| UMAP 降维 | CPU 密集 | 数据量大时可以增大min_dist以加速 |
| Leiden 聚类 | 内存 | 依赖图结构,多层迭代时耗时增加 |
7.3 降低内存占用的方法
一是过滤低质量细胞和基因。很多数据集中,大部分基因在少数细胞中表达,过滤掉后矩阵明显减小。
二是使用backed模式。Scanpy 支持不把所有数据读入内存,而是从磁盘按需读取:
adata = sc.read_h5ad("large_data.h5ad", backed="r")但要注意,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 无法连接 Kernel | Kernel 进程崩溃或 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 'scanpy' | Kernel 环境不是安装 Scanpy 的环境 | pip list | grep scanpy | 重新创建 Kernel:python -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 | 结束占用进程或使用--port=8889 |
读取.h5ad文件报错 | 文件路径不对或文件损坏 | 检查文件是否存在;打印工作目录 | 使用绝对路径;重新下载数据文件 |
sc.pp.neighbors非常慢 | 数据量太大、n_neighbors设置过大 | 检查数据规模;观察 CPU 使用率 | 先过滤低质量细胞;调整n_neighbors为 10-15 |
| UMAP 图上细胞聚成一团 | 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( filename="logs/analysis.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) try: # 分析代码 adata = sc.read_h5ad(data_path) logging.info(f"Loaded data with {adata.n_obs} cells") except Exception as e: logging.error(f"Error: {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 不要把所有功能塞进一个 Notebook
Notebook 并不是越长越好。一个 200 个单元格的 Notebook,运行到一半 Kernel 重启,前面的状态全部丢失,是非常糟糕的体验。建议按照阶段拆分为多个 Notebook:
- 01 数据读取与质控。
- 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。这样每次开新项目时,不用从空白开始,直接改路径和参数就能进入实际分析。