2、空间转录组数据特点:空间坐标、基因表达矩阵、稀疏性
接触空间转录组之前,我做了好几年单细胞测序。那时候觉得单细胞数据已经够头疼了——几万个细胞,几万个基因,矩阵稀疏得跟马蜂窝似的。直到第一次拿到空间转录组数据,我才意识到:真正的问题从来不是数据大,而是数据既大又有结构。空间坐标把每个点绑在了组织切片的具体位置上,这使得后续分析既充满机会,又处处是陷阱。
2.1 空间坐标:组织里的“经纬度”
空间转录组最直观的区别是什么?答案是每个检测点都有一个明确的物理位置。想象一下,一张小鼠脑切片上分布着几千个 spots(或 beads),每个 spot 的圆心坐标 (x, y) 就是它的“经纬度”。坐标数据通常长这样:
spot_id x_coord y_coord
spot_001 1024.5 789.2
spot_002 1024.6 790.1
spot_003 1025.0 788.9
...
注意这里的单位是像素,不是微米。不同平台的分辨率差很多——10x Visium 的 spot 直径约 55 μm,间距 100 μm;而 Slide-seq 的 beads 直径只有 10 μm,密度高得多。我曾在项目中混用过两个批次的数据,忘了做坐标系对齐,结果下游聚类一片混乱……嗯,从那以后我把坐标归一化写进了预处理流水线的第一步。
空间坐标最关键的特性是非均匀采样。组织切片不是规则的网格,有些区域(比如肿瘤边界)形态复杂,spots 会相对稀疏;而均匀的组织区域(比如肝实质)采样就比较密。这种非均匀性会直接影响后续的空间近邻构建,如果你直接用欧氏距离一刀切,很可能把不同结构域的 spots 强行连在一起。
2.2 基因表达矩阵:高维计数矩阵
每个 spot 除了坐标,还绑着一个 RNA 计数向量。把所有 spots 拼起来,就得到一个标准的基因表达矩阵:行是 spots(几千到几万个),列是基因(通常两万左右)。大部分平台输出的是 UMI 计数,也就是离散整数。
|| GeneA | GeneB | GeneC | ...
============================================
spot_001 || 0 | 12 | 5 | ...
spot_002 || 3 | 0 | 1 | ...
spot_003 || 0 | 0 | 0 | ...
...
这个矩阵和单细胞测序的计数矩阵在结构上没有本质区别,但有一个显著差异:每个 spot 往往包含多个细胞的 RNA。10x Visium 的一个 spot 直径覆盖 1-10 个细胞,具体取决于是什么组织。这意味着矩阵里的每个元素不是单个细胞的表达,而是一个混合信号。
我最初做差异表达分析时,直接套用了单细胞的 Wilcoxon 秩和检验,结果发现很多 marker 基因的 p 值非常显著但 fold change 极小。后来才意识到,混合信号稀释了差异的幅度,需要改用考虑空间自相关的方法。说白了,空间转录组的数据结构决定了下游分析必须专门处理“多细胞平均”效应。
| 特性 | 单细胞 RNA-seq | 空间转录组 |
|---|---|---|
| 观测单位 | 单个细胞 | spot / bead(含多细胞) |
| 坐标信息 | 无 | 有 (x, y) |
| 典型 spot / 细胞数 | 5K - 50K | 1K - 10K |
| 每个单元平均基因数 | 2000 - 5000 | 500 - 2000(因深度而异) |
| 基因表达矩阵稀疏度 | >90% | >80% 但受 spot 捕获效率影响 |
2.3 稀疏性:沉默的基因与噪声
不管是哪种空间转录组平台,你都会发现表达矩阵里一大堆零。为什么会这样?两个原因:一是基因本身在组织里就不表达(真的零),二是技术性丢失(dropout)。空间转录组的 dropout 率通常比单细胞高,因为每个 spot 的 RNA 捕获效率有限,尤其当 spot 包含的细胞数很少时。
我习惯先看一个简单指标——零率。比如用 Python 算一下:
import numpy as np
sparsity = np.mean(count_matrix == 0)
print(f"零率: {sparsity:.2%}")
# 输出: 零率: 87.34%
87% 的零率,也就是说矩阵里超过八成的位置都是 0。这个数字在单细胞里可能超过 95%,但空间转录组的零率也足够让很多经典算法崩溃。比如直接做 PCA,会看到第一个主成分被“测序深度”或“零比例”主导,根本看不见真正的生物学信号。
处理稀疏矩阵时,我个人会注意几个细节:
- 先过滤低表达基因:去掉在所有 spot 中表达计数总和 < 10 的基因,能有效降低矩阵维度,且不会丢失太多信息。
- 不要直接对原始计数做归一化:空间转录组的数据深度差异很大,有的 spot 只有几百个 UMI,有的却有上万。用传统的 CPM(每百万计数)归一化之前,最好先根据组织区域做分块归一化,否则边缘区域和中心区域的生信指标会有系统偏差。
- 稀疏矩阵存储:用
scipy.sparse.csr_matrix或anndata的稀疏格式。我见过有人直接把全矩阵塞进内存,几十 GB 直接爆了——其实空间转录组数据完全可以用稀疏表示,内存占用能降到原来的五分之一。
下面这张 SVG 图总结了空间转录组数据的三个核心特点以及它们之间的关系:
最后总结一下,空间转录组数据不像常规的表格数据。你得把坐标、矩阵、稀疏性三个特点同时装在脑子里,才能设计出合理的分析方案。我个人处理新数据集时,第一步永远是画一张 total_counts 的空间分布热图,看看测序深度有没有空间趋势;第二步算稀疏度,决定要不要走强过滤路线。这些习惯都是在踩过坑之后慢慢养成的——希望你能少走一些弯路。