假设你是一位刚接手“细胞杂货市场”的仓库管理员。你面前有一本砖头厚的账本,记录着几万个摊位(细胞)里几十种商品(基因)的备货数量(表达量)。这本账本厚到你看一眼就头皮发麻——怎么从里面找出规律?哪些摊位卖的是同类货品?市场里到底有几个大的商户群体? 这时你身边有两位得力助手。阿 Py(Scanpy)是 Python 出身的技术派,习惯写脚本批量处理,一条指令命令下去,一万个摊位瞬间处理完,所有操作自动留档;小 R(Seurat)是 R 语言出身的老牌分析师,习惯用图形界面交互操作,鼠标点选、框选、拖拽就能查看任意群体的细节,适合精细探查。两个人都能帮你完成“从账本到市场地图”的全流程:清理账本、统一标尺、寻找相似摊位、划分商圈、画市场地图。 这篇文章将带你从头认识这两套单细胞分析工具链:它们的数据结构有何不同、分析流程如何对照、可视化各自擅长什么、又该如何互相衔接。读完你就能根据自己团队的实际情况,做出务实的工具选型。
对于 AI+生命科学从业者,理解 Scanpy 与 Seurat 的异同是进入单细胞分析领域的必修课,能让你在组学数据处理的技术选型、团队协作与流程设计中少走大量弯路。
可视化演示
展示Scanpy(Python)与Seurat(R)单细胞分析工具链的完整流程对比,从质控归一化到聚类降维可视化,以及细胞群体在UMAP空间中的分布。切换模式查看不同维度,拖动滑块调节细胞数量。
本节配有交互动效(进入视口后自动加载,约 3KB)。
单细胞分析流程对比 Scanpy使用AnnData结构,Python生态集成度高 Seurat使用Seurat对象,R统计可视化生态丰富 QC → Normalize → HVG → PCA → Cluster → UMAP 两者流程相似但API与底层实现不同
工具缘起与定位
想象你的杂货市场第一天开业,你同时雇了阿 Py 和小 R 两位助理。阿 Py 是个年轻的程序员,他的工具架上挂满了 Python 脚本,他说:“给我一份数据清单,我能批量处理任何规模的市场,而且每一步都留日志,出错了随时回放。”小 R 则是一位稳重的统计学家,他的办公桌上摆着 RStudio 交互面板,他说:“我能让你用鼠标直接点选任意摊位,图表实时刷新,适合你这种喜欢亲眼确认的老板。”
这两位助理的“出身”决定了他们的性格。Scanpy 诞生于 Python 生态,由德国亥姆霍兹慕尼黑研究中心(Theislab 实验室)开发,核心数据结构是 AnnData,天然与深度学习框架(PyTorch、scVI)、云端集群和自动化流程亲和。Seurat 诞生于 R 语言生态,由纽约基因组中心(Satija Lab)开发,核心数据结构是 SeuratObject,背靠 R 语言在生物统计领域几十年的积累,配套 Shiny 可以做交互式网页应用。
尽管成长背景不同,两人处理的却是同一本账本——基因表达矩阵。这本矩阵行是细胞、列是基因,每个格子记录一个分子计数。无论你选哪位助理,第一步都是把这本账本读进他们的系统里。
所以,选助理的底层逻辑不是“谁更强”,而是“你的团队更习惯哪种工作方式”。Python 团队与机器学习流程自然拥抱 Scanpy,而 R 背景深厚的生物信息实验室往往更顺手 Seurat。
- 行标 i 与细胞矩阵每一行是一个细胞摊位,行数 n 表示市场里摊位总数。
- 列标 j 与基因矩阵每一列是一种基因商品,列数 m 表示商品种类总数。
- 元素 x_ij 表达量第 i 行第 j 列的元素记录该细胞里该基因的分子计数,是后续一切分析的原料。
数据结构对比
两位助理记账的方式完全不同。阿 Py 习惯用一个多标签页的工作簿(AnnData),主表格放在最前面,后面跟着一堆附属页签:细胞属性、基因属性、降维坐标、还有一张便签页记录杂七杂八的元信息。小 R 则习惯用一个分层档案柜(SeuratObject),主抽屉放表达数据,侧边抽屉放细胞元数据,底下还有专门的格子放降维结果和邻居图。
AnnData 的核心设计是“一个主矩阵配多个附属表”。主矩阵 X 保存表达量;obs 是按行(细胞)索引的元数据表——每个摊位来自哪个样品批次、线粒体比例多少;var 是按列(基因)索引的元数据表——基因 ID、基因名、是否高变基因;obsm 保存 PCA、UMAP 等降维坐标;uns 是自由格式的杂项记录。这种设计非常 Pythonic:一切围绕 NumPy 数组,切分、索引、广播都很自然。
SeuratObject 的核心设计是“以对象为容器,多模态并存”。assays 存放多个测定层(RNA、蛋白、ATAC 等),meta.data 存放细胞元数据,reductions 存放降维坐标,graphs 存放细胞间的邻居图结构。多模态数据(同一个细胞同时测了 RNA 和蛋白)可以直接放在同一对象里联合分析,这是 Seurat 的招牌能力。
理解了数据结构,你就明白为什么两个工具的分析习惯不同:Scanpy 让你像操作 DataFrame 一样自由地筛选细胞和基因;Seurat 则鼓励你把多组学数据装进一个对象里统一管理。没有谁绝对更好,而是“怎么组织,就怎么思考”。
- 档案夹对象AnnData 是一个整体容器,对应阿 Py 的多标签页工作簿。
- 主矩阵 X账本正文,n 行 m 列的表达矩阵,是所有分析的出发点。
- 细胞表 Oobs 存放每个摊位的属性,如样品名、批次、质控指标。
- 基因表 Vvar 存放每种商品的说明书,如基因名、染色体位置、高变标记。
- 降维结果 Robsm 存放 PCA/UMAP 坐标,相当于市场地图上每个摊位的平面坐标。
分析流程概览
不管是阿 Py 还是小 R,完成一次合格的单细胞分析都要走一套固定的“六步工序”,就像从大账本到市场地图的生产线。第一步,质量评估:把账本里明显破损的记录挑出来;第二步,归一化:统一每个摊位的备货标尺,让不同摊位可以公平比较;第三步,高变基因筛选:从几万种商品里挑出最能区分摊位的“招牌商品”;第四步,线性降维(PCA):先看整体大趋势;第五步,非线性降维与聚类:画出精细市场地图并划分商圈;第六步,标记基因识别与注释:给每个商圈挂上名字——“这是水果区,那是水产区”。
这套流程在 Scanpy 中由 sc.pp、sc.tl、sc.pl 三个模块接力完成;在 Seurat 中则由 NormalizeData、ScaleData、RunPCA、FindClusters、FindMarkers 等函数接力完成。函数名不同,节奏一致。
这套流程是两条工具链共同的地基。无论你最终选谁,最该花时间理解的不是某个 API 的用法,而是每一步“为什么要做”。流程理解到位了,切换工具只是换一套函数名而已。
- 原始账本X_raw 是刚拿到手的计数矩阵,还没经过任何处理。
- 归一化步骤f_归一化 把每个细胞的总计数统一到同一标尺。
- 降维步骤f_降维 把上万个基因的高维空间压缩到几十个主成分。
- 聚类步骤f_聚类 根据细胞间的相似性划分出自然群体。
- 注释步骤f_注释 结合已知标记基因给每个群体赋予生物学身份。
- 最终标签labels 是每个细胞对应的细胞类型,相当于市场分区图上各商圈的招牌。
预处理与质控
市场开业前,你得先做一次大扫除。有些摊位已经倒闭了,货架上空空如也(总表达量极低);有些摊位其实是两个人挤在一起摆的摊(双细胞 doublet),账目混在一起没法用;还有些摊位货物破损严重,细胞内线粒体基因的比例异常高——这在单细胞数据里是“细胞膜破损”的信号,相当于冷冻鱼化了冻,已经不能卖了。
质控(QC) 就是把这些坏摊位清出账本。常用指标有三个:每个细胞检测到的基因数(n_genes)、总分子计数(n_counts)、线粒体基因比例(pct_mt)。Scanpy 用 sc.pp.filter_cells 配合阈值过滤,Seurat 用 subset 函数,逻辑完全一样。
接着是归一化。因为测序深度不同,有的摊位记的账特别细(测序深),有的特别粗(测序浅),直接比较不公平。解决办法是把每个细胞的备货总量统一成“每万件商品中占比”——这就是 CP10K 归一化,再取对数压缩数值跨度。
质控与归一化是所有下游分析的“干净地基”。很多新手着急跑聚类,结果发现聚类结果全是批次(不同样品)而不是细胞类型——回头一看,正是质控阶段偷了懒。大扫除虽然枯燥,但决定整个市场地图的真实性。
- 原始分子数x_ij 是细胞 i 中基因 j 的原始计数,粗细不均不可直接比。
- 细胞总量缩放分母为该细胞所有基因计数之和,让每个细胞的总量归一到 1。
- 放大到万件乘以 10⁴,得到“每万件商品中该基因占几件”的直观数值。
- 对数压缩保护log₂(……+1) 压缩数值跨度,同时避免取对数为无穷。
降维与聚类
账本擦干净后,你要开始画市场地图了。可是商品有几万种,每个摊位是一个几万维空间里的点,人脑无法想象。于是先让阿 Py / 小 R 做降维:先用 PCA 找到数据变异最大的几个方向,把几万维压缩到几十个主成分——这就像你先从直升机上看城市,只判断“哪片是住宅区、哪片是工业区”。然后是 UMAP 或 t-SNE 这类非线性降维,把几十维进一步压到二维平面,生成一张人类能直接看懂的“商圈地图”。
地图画好后,聚类负责在图上划分边界。最常用的 Louvain / Leiden 算法先在细胞之间构建“邻居图”——每个细胞连向最像它的 k 个邻居,然后不断尝试切分社区,目标是让社区内部的连接比随机情况更紧密。这个目标用一个叫做模块度 Q 的分数来量化。
降维和聚类是一对配合:降维让大规模计算可行、可视化直观;聚类给出客观的群体划分。但要记住,聚类得到的只是“编号”,不是生物学答案。地图上画出的商圈还要靠下一步“注释”来命名验证。
- 邻居图连边A_ij 记录细胞 i 与细胞 j 在邻居图中是否有连接(1 有 / 0 无)。
- 随机期望连边k_i k_j / 2m 是两个细胞在随机连接时可能出现的期望边数。
- 总边数归一1/2m 让 Q 的取值范围收敛到 [-1, 1],便于跨数据集比较。
- 同社区判断δ(c_i, c_j) 在两细胞同属一个社区时取 1,否则为 0,只累加社区内部的超额连接。
可视化对比
两位助理画地图的风格差异,是很多团队选人的决定性因素。阿 Py(Scanpy)的地图风格是“简洁、静态、可批量产出”:sc.pl.umap 一张散点图,sc.pl.dotplot 一张气泡图,sc.pl.heatmap 一张热图,三张图拼成一张出版级图版就搞定。小 R(Seurat)的地图风格是“丰富、交互、可反复探索”:DimPlot、FeaturePlot、VlnPlot、DotPlot 一应俱全,配合 Shiny 还能生成让 PI 自己在网页上点选的交互面板。
更深一层,可视化算法的数学目标也值得理解。t-SNE 画地图时,希望高维空间里相似的细胞在二维图上依然靠近,这种“地图失真度”用 KL 散度 来度量:高维相似度分布 P 与低维相似度分布 Q 的差异越小,地图越忠实。
可视化是分析的“门面”,也是检查问题的第一道岗。聚类分群是否合理、批次效应是否残留、标记基因是否特异——一张 FeaturePlot 往往比一千行统计输出更直观。所以选工具时,一定要把“谁的地图更符合你团队的汇报习惯”算进成本里。
- 高维相似概率p_ij 表示高维空间中细胞 i 与 j 互为邻居的概率。
- 低维相似概率q_ij 表示二维地图上这两个细胞互为邻居的概率。
- 偏差比对数log(p/q) 量化“真实关系”与“图上关系”的偏离方向与程度。
- 全体求和对所有不重复细胞对求和,得到整张地图的总失真量,优化目标就是让它最小。
互操作与衔接
现实中的项目很少只用一个工具。很多实验室的现状是:生信老手用 Seurat 做前期的质控与可视化探索,把数据打磨干净;AI 工程师接手后要用 Scanpy 把数据送进深度学习模型(如 scVI、CellTypist)。这时候“账本翻译”就成了刚需——两位助理的档案格式不同,但账本内容是同一本。
翻译的桥梁是标准文件格式。Scanpy 的 AnnData 可以保存为 .h5ad;Seurat 对象可以保存为 .rds 或转成 .h5seurat。通过 SeuratDisk 包可以双向转换:Convert("data.h5ad", "h5seurat", overwrite=TRUE),反过来用 ReadH5AD 也能读。此外,.loom 和 .h5 是两家都承认的中间格式。
不过翻译有“注意事项”:基因 ID 到底是用的是 Symbol(如 CD3D)还是 Ensembl ID(如 ENSG00000167286),两边必须一致,否则合并后基因对不上;表达矩阵是原始 counts 还是归一化后的值,也要在转换前确认好;细胞 barcode 不能有重复。批次效应(不同样品或不同实验批次的技术差异)通常在整合时统一处理,Scanpy 支持 BBKNN、Harmony,Seurat 支持 Harmony、RPCA 等,两边结果可以互相认。
- R 侧矩阵X_Seurat 是 Seurat 对象中保存的表达矩阵。
- Python 侧矩阵X_Scanpy 是 AnnData 中保存的表达矩阵。
- 双向转换通过 h5ad / h5seurat / loom 等格式,两套工具可以互相读取对方的数据。
- 维度不变转换只改格式不改数据,行数 n(细胞数)与列数 m(基因数)保持不变。
选型与实战建议
最后回到那个最实际的问题:我的项目到底该用谁?答案不是“看哪个教程多”,而是看你的团队构成和数据规模。
如果团队以 Python / 机器学习背景为主,未来要做大量深度嵌入、模型训练、云端流程调度,那么 Scanpy 是自然选择——h5ad 支持内存映射(mmap),百万级细胞也能在普通服务器上流畅处理,配合 scvi-tools、squidpy 等扩展生态非常顺滑。如果团队以 R / 生信传统背景为主,日常产出以探索性图表和交互式报告为主,那么 Seurat 更顺手——它的图形语法、Shiny 集成和丰富的在线教程让新手更容易上手。
如果数据规模特别大(例如人类细胞图谱项目超过百万细胞),Scanpy 的内存效率优势会明显放大;而如果项目强调多组学联合分析(RNA + 蛋白 + ATAC 同时测),Seurat 的多模态对象设计更省心。当然,更常见的现实是“混合工作流”:Seurat 做前期打磨,Scanpy 做批量整合和模型嵌入,最后再回 Seurat 画图汇报。选型不是站队,而是排兵布阵。
没有哪套工具是银弹。真正专业的工作流,往往是“让合适的人用合适的工具干合适的活”——理解了这一点,你就从“工具的使用者”进阶为“分析方案的架构师”。
- 生态契合度E 代表团队成员既有的语言熟练度与代码资产匹配程度。
- 规模性能P 代表工具在海量细胞数据处理中的内存与速度表现。
- 交互可视化C 代表交互式探索、图表定制与汇报呈现的便利程度。
- 加权总分把三项按 0.4 / 0.3 / 0.3 的权重相加,就是可比较的选型分。
AI 应用场景
肿瘤免疫微环境解析
阶段:数据分析与细胞注释
解决的问题:传统流式细胞术一次只能看十几个标记物,无法在数万个细胞中无偏发现稀有亚群。单细胞测序配合 Seurat 的完整分析流程,能在全转录组尺度上自动划分细胞群体并注释身份。
具体案例:某肿瘤样本用 Seurat 跑完质控 → 归一化 → 聚类 → marker 注释后,发现一群此前被忽略的 CD8+ 耗竭 T 细胞。研究团队再结合轨迹分析定位其分化路径,为免疫治疗靶点筛选提供了直接线索。整个过程从原始数据到细胞图谱,完全在 Seurat 的图形化工作流中完成。
跨语言团队的混合分析流水线
阶段:数据工程与模型训练衔接
解决的问题:实验室传统上使用 Seurat 做可视化探索,而深度学习团队需要用 Python 框架(如 scVI、CellTypist)训练细胞嵌入模型。两套工具格式不通,导致协作断裂、重复造轮子。
具体案例:某项目组先用 Seurat 完成质控与归一化,通过 SeuratDisk::Convert 转成 h5ad;Scanpy 读入后直接对接 scVI 训练潜空间表示,再用 scanpy.read_h5ad 把结果导出;最后转回 Seurat 对象,在原有流程里完成论文级可视化。整个混合流水线两天跑通,两组成员各自发挥所长。
大规模细胞图谱构建
阶段:规模化数据集成
解决的问题:构建器官级或物种级细胞图谱需要处理数十万到上百万细胞,R 对象在内存中容易爆掉,流程需要支持集群调度和断点续跑。
具体案例:某人类细胞图谱子项目包含 120 万细胞、三个捐赠者、八个批次。团队选择 Scanpy + h5ad 内存映射做全量整合,用 Harmony 做批次校正,Leiden 聚类完成后,将各亚群子集导出到 Seurat 做精细可视化与标记基因审查。Scanpy 负责“扛重活”,Seurat 负责“精打磨”,各取所长。
Python 演示
"""从零实现单细胞分析核心流程:质控 -> 归一化 -> 高变基因 -> PCA -> 聚类"""import numpy as np def generate_demo_data(n_cells=600, n_genes=2000, seed=42): """生成模拟单细胞表达矩阵:4 种细胞类型,每种有专属高表达基因,含10%破损细胞""" rng = np.random.RandomState(seed) X = rng.poisson(0.5, size=(n_cells, n_genes)).astype(float) types = [] n_each = n_cells // 4 for ci in range(4): for i in range(ci * n_each, (ci + 1) * n_each): if rng.rand() < 0.1: X[i] = 0 X[i, :10] = rng.poisson(1, size=10) else: X[i, ci * 50:(ci + 1) * 50] += rng.poisson(5, size=50) types.append(ci) return X, np.array(types) def quality_control_mask(X, min_counts=30, max_counts=2000): """质控:保留总表达量适中的细胞(模拟摊位整洁度检查)""" counts = X.sum(axis=1) return (counts >= min_counts) & (counts <= max_counts) def normalize_cp10k(X, target=1e4): """CP10K 归一化 + log1p 对数变换""" X_norm = X / X.sum(axis=1, keepdims=True) * target return np.log1p(X_norm) def select_hvg(X, top=50): """高变基因筛选:按表达方差取 top K""" variances = X.var(axis=0) return np.argsort(variances)[-top:] def run_pca(X, n_components=20): """PCA 主成分分析:特征分解协方差矩阵求主方向""" Xc = X - X.mean(axis=0) cov = np.cov(Xc.T) _, eigvecs = np.linalg.eigh(cov) return Xc @ eigvecs[:, -n_components:] def kmeans(X, k=4, iters=20): """KMeans 聚类:迭代更新簇中心""" rng = np.random.RandomState(0) centers = X[rng.choice(len(X), k, replace=False)] for _ in range(iters): dists = np.linalg.norm(X[:, None, :] - centers[None, :, :], axis=2) labels = dists.argmin(axis=1) for c in range(k): if np.any(labels == c): centers[c] = X[labels == c].mean(axis=0) else: centers[c] = X[rng.choice(len(X))] return labels def match_accuracy(pred, truth): """把聚类簇号映射到真实类型,计算匹配准确率""" mapping = {} for p in np.unique(pred): majority = np.bincount(truth[pred == p]).argmax() mapping[p] = majority mapped = np.array([mapping[p] for p in pred]) return (mapped == truth).mean() def main(): X, truth = generate_demo_data() mask = quality_control_mask(X) X, truth = X[mask], truth[mask] print(f"质控保留 {len(truth)}/600 个细胞") X = normalize_cp10k(X) genes = select_hvg(X, top=50) pc = run_pca(X[:, genes], n_components=20) pred = kmeans(pc, k=4) print(f"聚类准确率: {match_accuracy(pred, truth):.1%}") if __name__ == "__main__": main()
X[i, ci * 50:(ci + 1) * 50] += rng.poisson(5, size=50)给每种细胞类型注入 50 个专属高表达基因,模拟“细胞身份指纹”。mask = quality_control_mask(X)用总表达量阈值筛掉低质量细胞,相当于清退空置或破损摊位。X / X.sum(axis=1, keepdims=True) * targetCP10K 归一化,把每个细胞总量统一成一万份再算占比。return np.log1p(X_norm)log1p 对数压缩,避免高表达基因在数值上碾压低表达基因。variances = X.var(axis=0)逐基因计算方差,方差大的基因更可能是区分细胞类型的“招牌商品”。np.cov(Xc.T)中心化后计算基因协方差矩阵,这是 PCA 求主方向的输入。Xc @ eigvecs[:, -n_components:]把数据投影到方差最大的 20 个主成分方向,完成线性降维。np.linalg.norm(X[:, None, :] - centers[None, :, :], axis=2)广播计算每个细胞到所有簇中心的欧氏距离。centers[c] = X[labels == c].mean(axis=0)把簇中心更新为组内细胞的均值,若空簇则随机初始化。maj = np.bincount(truth[pred == p]).argmax()用多数投票将聚类编号映射到真实细胞类型,用于评估准确率。
常见误区
误区很多新手以为这两个工具是竞争对手,项目一开始就要“站队”,选了 Seurat 就不能碰 Scanpy,反过来也一样。看到同事两个都在用,就觉得不专业。
正解两者通过 h5ad、h5seurat、loom 等格式可以双向转换,实际工业界最常见的做法恰恰是混合使用——Seurat 做交互式探索与质控,Scanpy 做大规模整合和深度学习嵌入,最后再转回 Seurat 出图。工具是手段,分析目标才是目的。
为何常见:市面上的教程大多只讲其中一个工具,社区讨论也常常“各自为营”,导致初学者误以为两者是互斥选项。
误区看到 `log1p` 归一化后的矩阵,以为这些数字仍然代表基因的绝对分子数,直接拿两个细胞、两个基因之间的归一化值比较大小,甚至算“倍数变化”。
正解归一化后的数值只是“相对丰度”,相当于把每个摊位总量统一成一万件后算出的占比。它能用来比较“基因 A 在细胞 X 中是否比在细胞 Y 中相对更高”,不能用来回答“基因 A 在细胞 X 里到底有多少个分子”。后一个问题必须回到原始 counts 才能回答。
为何常见:归一化后的数字看起来还是“计数”,加上教程常说的“标准化”一词过于笼统,很容易让人忘记中间发生过缩放变换。
误区Leiden 聚类输出 0、1、2、3 编号,初学者就把 0 号群当成“T 细胞”、1 号群当成“B 细胞”,以为聚类结果就是生物学答案。
正解聚类只找到“统计上的群体结构”,它不知道这些群体是什么细胞。你必须用标记基因(如 CD3D 对应 T 细胞)逐一验证每个簇的表达特征,再结合生物学知识命名;同一群可能含有稀有亚群,也可能被过分割。商圈边界只是统计结果,“这里是水果市场”需要实地走访才能定论。
为何常见:软件输出编号太像“结论”,加上新手还不熟悉标记基因注释这一步,容易把计算中间结果当最终答案。
误区对着 UMAP 散点图说:“这两个点挨在一起,它们肯定是一类细胞;这两个点隔得远,差异一定很大。” 甚至用图上距离量化细胞差异。
正解UMAP 的首要目标是保持“局部结构”,它会刻意压缩或拉伸全局距离。图上相邻的细胞确实大概率相似,但图上很远的两个点,真实差异可能很大也可能很小。想严谨比较差异,应该回到 PCA 空间或直接看标记基因表达量。地图上两个摊位挨得近,不代表卖的一样。
为何常见:人脑天然把二维距离理解为差异程度,而 UMAP 这种非线性降维图恰恰打破了这种直觉,初学者很容易被“看起来像地图”欺骗。
面试题
Q1. Scanpy 是哪种编程语言生态中的单细胞分析工具?
- A.Python 生态分析工具← 正确答案
- B.R 语言生态分析工具
- C.Java 生态分析工具
- D.C++ 生态分析工具
答案:A。Scanpy 基于 Python 生态,核心数据结构是 AnnData,常用在深度学习与流程自动化场景;Seurat 才是 R 生态的工具。记住“Scanpy 配 Python,Seurat 配 R”这对搭档即可。
Q2. Seurat 中典型的单细胞数据结构是什么?
- A.AnnData 对象
- B.SeuratObject 对象← 正确答案
- C.DataFrame 数据表
- D.NumPy 多维数组
答案:B。Seurat 以 SeuratObject 为容器,内部包含 assays 表达数据、meta.data 细胞元数据和 reductions 降维坐标。AnnData 是 Scanpy 的对象,DataFrame 和 NumPy 数组只是底层存储的一环。
Q3. 单细胞质控中,线粒体基因比例过高通常反映什么?
- A.细胞代谢非常旺盛
- B.细胞膜破损或已死亡← 正确答案
- C.基因测序出现错误
- D.数据格式不正确
答案:B。线粒体基因比例过高是单细胞数据的经典“破损信号”——细胞破裂后胞质 mRNA 流失而线粒体 RNA 相对保留,类似冷冻鱼化冻后不再新鲜,这类细胞应在质控阶段过滤掉。
Q4. Scanpy 中常见的细胞水平归一化处理是?
- A.按每个细胞总量缩放后取对数← 正确答案
- B.按每个基因中位数中心化
- C.对所有数值整体做最大最小值归一化
- D.直接对原始计数做 Z-score 标准化
答案:A。单细胞归一化的标准做法是 CP10K/CPM——先按细胞总量缩放(如每万分子占比),再取 log1p 压缩动态范围。按基因中心化或整体 min-max 缩放无法校正不同细胞间测序深度的差异。
Q5. PCA 线性降维选择的坐标方向满足什么性质?
- A.数据投影后方差最大← 正确答案
- B.数据投影后方差最小
- C.让类别之间的间距最小
- D.让每个类别样本数相等
答案:A。PCA 的目标是找到数据变异最大的正交方向,投影后方差越大代表信息保留越多,相当于从直升机上找到最能区分地面的“大趋势”。方差最小、间距最小等说法都与 PCA 的设计初衷相反。
Q6. 关于 UMAP 与 t-SNE,下列说法正确的是?
- A.UMAP 更注重保持局部结构← 正确答案
- B.t-SNE 能很好地保留全局距离关系
- C.UMAP 计算速度通常更快← 正确答案
- D.两者都能保留全局距离关系
答案:AC。UMAP 和 t-SNE 都优先保局部结构,但二者都会扭曲全局距离,B 和 D 都不成立。UMAP 由于使用更高效的图算法,在大数据集上通常明显快于 t-SNE,因此成为当前单细胞可视化的默认选择。
Q7. Louvain/Leiden 聚类优化的模块度 Q 表示什么?
- A.社区内部连接比随机期望更紧密的程度← 正确答案
- B.每个细胞总表达量的大小
- C.基因变异程度的强弱
- D.批次效应强度的指标
答案:A。模块度把“实际社区内部连边数”与“随机连接假设下的期望连边数”做差并归一化。Q 越高说明划分出的社区越“货真价实”,类似商圈内部商户往来越频繁,越说明这是一个真正的商圈。
Q8. Scanpy 与 Seurat 互相转换数据时,需要注意哪些事项?
- A.基因 ID 使用的是 Symbol 还是 Ensembl ID← 正确答案
- B.表达量是原始计数还是归一化后的值← 正确答案
- C.细胞 barcode 是否存在重复← 正确答案
- D.转换前必须先完成批次校正
答案:ABC。转换的本质是换装订不改账本,但基因 ID 类型不一致会导致合并错位、表达量类型混乱会误导下游分析、barcode 重复会造成索引冲突。批次校正是分析流程中的一个环节,不是格式转换的前提,转换后再做完全可行。
Q9. 要处理百万级细胞数据且追求内存效率与批处理自动化,更推荐?
- A.Seurat 因为可视化交互体验更好
- B.Scanpy 因为 h5ad 支持内存映射← 正确答案
- C.用 Excel 逐批人工检查最稳妥
- D.两者的内存表现完全一样
答案:B。Scanpy 基于 h5ad 格式支持内存映射(mmap),百万级矩阵无需全部加载进内存即可切片计算,配合集群调度天然适合大规模自动化。Seurat 的交互体验虽好,但全对象常驻内存在大数据上会吃紧。Excel 处理单细胞数据则完全不现实。
Q10. 关于批次整合与互操作,下列说法错误的是?
- A.BBKNN 可以用于批次校正
- B.整合后的降维坐标无法导出← 正确答案
- C.批次整合应在聚类前完成
- D.合并样本前无需任何批次处理← 正确答案
答案:BD。BBKNN 是 Scanpy 常用的批次校正方法,A 正确;整合后的降维坐标保存在 reductions 里,可随 h5ad/h5seurat 正常导出,B 错误;批次校正应在聚类前完成,否则聚类会按批次而非生物学差异分群,C 正确;不同样本/批次合并通常需要批次处理,D 错误。题目问“错误的”,故选 B、D。