3. 数据获取与格式

开始空间聚类之前,得先把原材料搞到手。说白了,你得知道数据该从哪下载、下载下来长什么样、哪些文件是核心、哪些是坑。我以前刚接触 Visium 时,对着满目录的文件一脸懵,还试过把图像坐标和表达矩阵对错位——那叫一个惨。今天我们就把这部分彻底理清。

3.1 从 10x Genomics 官网下载公开 Visium 数据

10x 官网提供了多个公开数据集,我常用的是 Visium 小鼠大脑(前额叶冠状切片)。下载方式很简单:用 wget 或 curl 拉两个文件——一个 H5 表达矩阵,一个包含图像和空间信息的压缩包。

# 下载示例(我习惯用 wget)
wget https://cf.10xgenomics.com/samples/spatial-exp/1.1.0/V1_Adult_Mouse_Brain/V1_Adult_Mouse_Brain_filtered_feature_bc_matrix.h5

wget https://cf.10xgenomics.com/samples/spatial-exp/1.1.0/V1_Adult_Mouse_Brain/V1_Adult_Mouse_Brain_spatial.tar.gz

tar -xzf V1_Adult_Mouse_Brain_spatial.tar.gz

解压后会得到一个 spatial/ 目录和 filtered_feature_bc_matrix.h5。我个人建议下载 filtered 版本,它已经去掉了空液滴,实验初期够用了。想用原始数据?下载 raw_ 版就行,但后续清洗会多一步。

提示:10x 官网的下载链接结构基本固定,你可以把 V1_Adult_Mouse_Brain 换成其他数据集名(比如人乳腺癌),只要目录对就能直接下载。疫情期间我批量拉了一堆,省了不少手工操作。

3.2 理解 H5 文件的结构

H5(HDF5)是一种层次化数据格式,像迷你文件系统。你用 h5py 打开就能看到里面的“文件夹”和“文件”。我把代码贴在下面,你跑一下就知道有多直观了。

import h5py

f = h5py.File('filtered_feature_bc_matrix.h5', 'r')
print(list(f.keys()))         # ['matrix']
g = f['matrix']
print(list(g.keys()))         # ['barcodes', 'data', 'indices', 'indptr', 'shape', 'features']

关键数据集解释:

  • barcodes:所有 spot 的条形码序列,顺序就是表达矩阵的列顺序。
  • features:基因信息,里面又有 id、name、feature_type、genome 四个子数据集。
  • data / indices / indptr:压缩稀疏列(CSC)格式的三个数组,共同构成表达矩阵。
  • shape:矩阵维度,比如 32285 个基因 × 4992 个 spot。

我第一次用 h5py 读时,以为 features 是直接可读的二维表,结果它也是个组。嗯,这里要注意:你要用 f['matrix/features/name'][:].astype(str) 才能拿到基因名列表。

警告:H5 内存储的 barcodes 默认是 bytes 类型,记得用 .astype(str) 转换。我曾经因为忘记转码,写出的 CSV 全是 b'...',排查了半天。

用 scanpy 读取其实更方便,但你理解底层结构后,调试异样数据时才不会抓瞎。我建议至少用 h5py 看一次结构。

3.3 SpaceRanger 输出目录结构

SpaceRanger 是 10x 官方的处理流程,输出都放在 outs/ 目录下。下面是一个典型结构的简化版:

outs/
├── analysis/
│   ├── clustering/
│   │   ├── graphclust/
│   │   └── kmeans/
│   ├── diffusion/
│   └── pca/
├── spatial/
│   ├── tissue_positions_list.csv    # spot 坐标(行列号)
│   ├── scalefactors_json.json       # 缩放因子
│   ├── tissue_hires_image.png       # 高分辨率组织图像
│   ├── tissue_lowres_image.png      # 低分辨率(通常用于绘图)
│   └── aligned_tissue_image.jpg     # 已对齐的荧光图像
├── filtered_feature_bc_matrix.h5    # 过滤后的表达矩阵
└── raw_feature_bc_matrix.h5         # 原始表达矩阵

我找重点给你说:

  • spatial/tissue_positions_list.csv:每行一个 spot,包含 barcode、in_tissue(0/1)、row、col、pxl_row_in_fullres、pxl_col_in_fullres。坐标原点在图像左下角。
  • scalefactors_json.json:里面有 tissue_hires_scalef、tissue_lowres_scalef、spot_diameter_fullres 等关键参数。图像配准和可视化时必须有它们。
  • analysis/:SpaceRanger 自动跑的聚类、PCA 等结果。在自定义分析中我们通常忽略它,直接用自己的流程。
核心逻辑: 表达矩阵的列(barcodes)和 tissue_positions_list.csv 的 行顺序必须一致。SpaceRanger 保证了这一点,但如果你自己拼接多个样本,一定要重新对齐 barcode 序列,否则图像坐标和表达数据会匹配错。

3.4 几个常见的坑——我都踩过

你想想看,数据拿到手,看起来一切正常,结果一画图全是空的——大概率是下面这几个问题:

  1. barcode 顺序错位。 我刚开始用 scanpy 直接读 H5,再手工读 CSV,以为顺序天然匹配。事实是,H5 里的 barcodes 和 CSV 里的 barcode 都是字符串,但 CSV 的排序列可能不同。你一定要用 pandas merge 来匹配。
  2. 缩放因子用错。 把低分辨率图和高分辨率坐标混在一起,结果 spot 全堆在图像角落。我之前就是这么干的,画出的聚类图像一团乱麻。正确处理方式:用 tissue_lowres_scalef 把全分辨率坐标缩放到低分辨率图。
  3. H5 里的 matrix 是稀疏格式,直接装进 pandas 会爆内存。 以前我硬生生转成稠密数组,12GB 内存直接挂掉。后来都用 sparse 矩阵处理。

下面我用一个 SVG 图把整个数据获取到目录结构串起来,让你一眼看清全局。

Visium 数据获取与文件结构 10x Genomics 官网下载 filtered_feature_bc_matrix.h5 barcodes matrix features spatial.tar.gz → outs/spatial/ tissue_positions.csv 图像 scalefactors.json ⚠️ 关键依赖关系 表达矩阵的 barcode 顺序 = tissue_positions_list.csv 的顺序 图像缩放时需使用 scalefactors_json.json 中的对应因子 合成 AnnData 对象用于分析

3.5 本章核心要点速查

文件/目录 作用 使用频率
filtered_feature_bc_matrix.h5 过滤后的基因×spot 表达矩阵(稀疏 CSC) 每次分析必用
spatial/tissue_positions_list.csv spot 的像素坐标和行/列网格位置 每次分析必用
spatial/scalefactors_json.json 图像缩放因子、spot 直径等元信息 每次可视化必用
spatial/tissue_lowres_image.png 低分辨率组织图像(通常用于绘制最终图) 每次可视化必用
spatial/tissue_hires_image.png 高分辨率图像(用于精细配准或导出) 低频使用
analysis/ SpaceRanger 自动分析结果(可忽略) 极少使用