第4章 数据获取与格式:Spaceranger输出解析、h5文件、MEX格式、AnnData对象
Pipeline跑完了,数据出来了。但你知道这些文件是干嘛的吗?
很多新手一上来就被一堆目录和文件搞懵了。明明跑成功了,却不知道从哪下手。我刚开始接触空间转录组时也这样——对着outs目录发了好几天呆。
这一章我们就来拆解Spaceranger的输出。弄清楚h5、MEX、AnnData这三种格式到底是什么关系。说白了,就是搞明白“数据在哪里、长什么样、怎么读进Python”。
4.1 Spaceranger输出目录结构
跑完Spaceranger count后,会生成一个输出目录。默认是你指定的--id参数值。我个人习惯先用tree看一眼整体结构:
tree -L 2 /path/to/sample_output/
你会看到类似这样的布局:
sample_output/
├── outs/
│ ├── filtered_feature_bc_matrix.h5
│ ├── filtered_feature_bc_matrix/
│ │ ├── matrix.mtx
│ │ ├── features.tsv
│ │ └── barcodes.tsv
│ ├── raw_feature_bc_matrix.h5
│ ├── raw_feature_bc_matrix/
│ ├── spatial/
│ │ ├── tissuelist.csv
│ │ ├── scalefactors_json.json
│ │ └── hires_image.png
│ ├── analysis/
│ └── web_summary.html
└── ...
核心数据都在outs/里。其中最重要的就是filtered_feature_bc_matrix——这是过滤后的表达矩阵。你想想看,后续所有分析都基于这个文件。
web_summary.html,确认质控指标没问题。然后再去碰矩阵文件。这样能快速定位问题,避免在错误的数据上浪费时间。
4.2 h5文件格式详解
h5格式是10x官方提供的单文件存储方案。它把矩阵数据、基因特征、barcode信息全塞进一个文件里。好处是方便传输和归档。
用Python读取非常直接:
import h5py
f = h5py.File("filtered_feature_bc_matrix.h5", "r")
print(list(f.keys()))
# 输出: ['matrix', 'matrix_features', 'matrix_barcodes']
# 查看矩阵形状
matrix_grp = f['matrix']
print(matrix_grp['data'].shape)
# 输出: (非零元素个数,)
里面包含三个主要组:matrix存的是稀疏矩阵的COO格式(data、indices、indptr),matrix_features是基因信息,matrix_barcodes是细胞barcode。
data当成完整矩阵去算均值——结果算出来全是错的。那个data只存了非零值,必须还原成完整矩阵才能做统计。嗯,这里一定要注意。
4.3 MEX格式详解
MEX格式是Market Exchange Format的缩写。它用目录+三个文件来存储矩阵。相比h5,它更直观——你可以直接用文本编辑器打开看内容。
标准的MEX目录包含:
filtered_feature_bc_matrix/
├── matrix.mtx # 稀疏矩阵,COO格式
├── features.tsv # 基因信息(id、name、type)
└── barcodes.tsv # 细胞barcode列表
matrix.mtx的内容长这样:
%%MatrixMarket matrix coordinate real general
33538 7864 12345678
1 1 5
1 2 0
2 1 3
...
第一行是注释,第二行是“基因数 细胞数 非零元素数”。后面每行是“基因索引 细胞索引 表达值”。注意索引是从1开始的。
用R或Python读MEX都很方便:
import scanpy as sc
adata = sc.read_10x_mtx(
"filtered_feature_bc_matrix/",
var_names='gene_symbols',
cache=True
)
这一行代码就把整个矩阵读进来了。为什么推荐用sc.read_10x_mtx?因为它自动处理了索引偏移、基因名去重、barcode格式化。省心。
4.4 AnnData对象:统一的数据容器
在Python生态里,我们最终都会把数据转成AnnData对象。scanpy、squidpy、tangram这些工具全都围绕AnnData设计。它就像个“数据集装箱”——把矩阵、注释、空间坐标、图像全装在一起。
从h5或MEX转成AnnData非常简单:
import scanpy as sc
# 从MEX读取
adata = sc.read_10x_mtx("filtered_feature_bc_matrix/")
# 或者从h5读取
adata = sc.read_10x_h5("filtered_feature_bc_matrix.h5")
# 添加空间坐标
adata.obsm['spatial'] = spatial_coords # numpy array, shape (n_cells, 2)
print(adata)
# 输出: AnnData object with n_obs × n_vars = 7864 × 33538
# obsm: 'spatial'
AnnData核心结构就这几个:
X: 表达矩阵(默认是稀疏矩阵,节省内存)obs: 细胞元数据(barcode、聚类标签、UMAP坐标等)var: 基因元数据(基因名、高变基因标记等)obsm: 细胞级多维矩阵(空间坐标、降维结果)uns: 非结构化数据(配色、参数、图像)
我建议在数据读取阶段就直接转为AnnData。否则后面每换一个工具就要重新读一次数据,烦得很。
4.5 三种格式对比与选择建议
到底用哪种?我整理了一个表格:
| 维度 | h5文件 | MEX格式 | AnnData对象 |
|---|---|---|---|
| 存储形式 | 单文件(二进制) | 目录+3个文本文件 | 内存对象(可序列化) |
| 可读性 | 需编程读取 | 可直接用文本编辑器查看 | 需在Python中查看 |
| 包含信息 | 矩阵+基因+barcode | 矩阵+基因+barcode | 矩阵+元数据+空间+分析结果 |
| 读取速度 | 快(二进制IO) | 中等(文本解析) | 取决于来源格式 |
| 适用场景 | 归档、传输、长期存储 | 快速检查、兼容老工具 | 分析全流程、多工具协作 |
我个人更倾向于这么用:原始数据用h5归档,日常分析用AnnData。MEX格式只在需要快速查看矩阵内容时才用。说白了,AnnData才是你真正干活时的核心。
var里基因名有重复,导致下游分析全乱套。建议读取后第一时间执行adata.var_names_make_unique()。就一行代码,能省你三天排查时间。
到这,你应该对三种格式有了清晰的认识。从Spaceranger输出到AnnData,这条路其实很直接。记住一点就行:h5和MEX只是存储方式,AnnData才是你分析时的主战场。