2. 科学数据格式分类与核心特征
面对 NetCDF、HDF5、Zarr、Parquet、CSV、JSON、TIFF 等众多格式,初学者最常见的困惑是"到底该用哪一个"。要回答这个问题,不能靠记忆格式清单,而应建立一套可比较的维度框架。本节从存储模型、元数据能力、压缩与分块、并行 I/O 支持四个核心维度出发,把格式的"性格"拆解清楚,再给出可操作的选型判断路径。
维度一:存储模型决定访问模式
存储模型是格式最本质的特征,它决定了数据在磁盘上的组织方式,也直接决定了什么样的查询是"便宜"的、什么是"昂贵"的。可以归纳为四类:
- 行式存储:同一记录的所有字段连续存放,如 CSV、JSON Lines。适合逐条读取完整记录的场景,但只取某一列时也必须扫描整行。
- 列式存储:同一字段的所有值连续存放,如 Parquet、Arrow IPC。适合"取少数列、聚合大量行"的分析型负载,列裁剪和向量化计算效率高。
- 数组式存储:以多维数组为基本单位,按维度索引寻址,如 NetCDF、HDF5、Zarr、TIFF。适合网格化科学数据,如气候场、遥感影像、仿真结果。
- 层次式存储:以树状组/数据集结构组织,如 HDF5、NetCDF-4、Zarr 的 group 层级。适合把异构数据(多个变量、多个实验组)收纳进单一容器。
需要注意,数组式与层次式并不互斥:NetCDF-4 底层基于 HDF5,既有多维数组变量,也有 group 层次;Zarr 同样支持层级 group。选型时应先问"我的主要访问模式是整行、整列还是多维切片",再问"是否需要把多组数据装进一个文件"。
维度二:元数据能力决定数据能否自解释
科学数据若缺少单位、坐标轴、缺失值标记、仪器参数等描述,就只是"裸数字"。元数据能力可从三个层次评估:
- 结构元数据:字段名、数据类型、维度长度、形状。CSV 只有表头,类型需推断;Parquet 在文件尾写入 schema;NetCDF/HDF5 显式记录维度与类型。
- 语义元数据:单位、坐标参照、标定系数、缺失值填充值。NetCDF 的
units、_FillValue、scale_factor属约定属性,配合 CF 规范可实现自描述;Zarr 通过.zattrs承载同类信息。 - 溯源元数据:处理历史、软件版本、输入文件清单。HDF5/NetCDF 可挂任意属性组,适合记录 provenance;纯文本格式则需外部约定。
实践判断标准很简单:把文件单独发给同事,他能否不看文档就正确解读数值含义? 若不能,说明元数据能力不足或未被使用。
维度三:压缩与分块决定 I/O 效率
压缩降低存储成本,分块(chunking)则决定随机访问的粒度,两者常需联合设计。以 NetCDF-4/HDF5 为例,一个形状为 (time=8760, lat=180, lon=360) 的逐小时气温场,若按整数组连续存储,读取单个时刻的切片需跨越整个文件;若设置 chunk 为 (24, 180, 360),则读取一天的数据只需命中一个块。
# 以 xarray 写出分块 + 压缩的 NetCDF-4 示例(示例参数,非实测)
ds.to_netcdf(
"temp_2023.nc",
engine="netcdf4",
encoding={
"t2m": {
"zlib": True,
"complevel": 4,
"chunksizes": (24, 180, 360),
"dtype": "float32",
}
},
)
这里 complevel=4 是压缩强度与速度的折中;chunksizes 应尽量匹配典型访问模式——若主要按时间序列取点,则 chunk 应偏向时间维;若主要取空间场,则 chunk 应偏向空间维。Zarr 把每个 chunk 存为独立对象,天然适合云对象存储的并行读取;Parquet 则以 row group + column chunk 实现列级裁剪与谓词下推。
维度四:并行 I/O 支持决定能否扩展
当数据量超过单机内存或单盘带宽,并行能力成为瓶颈。评估要点包括:是否支持多进程/多节点并发写同一文件(如 HDF5 的 MPI-IO 驱动、NetCDF-4 并行模式);是否支持分片并行读(Zarr 的 chunk 天然可并行,Parquet 可按 row group 切分);是否与分布式计算框架(Dask、Spark)有成熟适配。CSV 与单体 JSON 在这方面的能力最弱,通常需要先切分文件再并行处理。
把四个维度合成选型判断
实际选型时,四个维度往往互相牵制,需要按优先级排序。一个可操作的判断顺序是:
- 先定访问模式:若数据是规则多维网格(时间×空间×变量),优先数组式(NetCDF/Zarr/HDF5);若是表格型记录且以列聚合为主,优先列式(Parquet);若只是小规模交换与人工查看,CSV/JSON 足够。
- 再定部署环境:本地单机大文件用 HDF5/NetCDF-4;云对象存储与分布式读取用 Zarr;数据仓库生态用 Parquet。
- 然后定元数据要求:需要 CF 规范自描述与单位语义,选 NetCDF;需要灵活挂载任意属性与溯源,选 HDF5;元数据简单则不必上重格式。
- 最后调分块与压缩:依据典型切片形状设置 chunk,压缩级别在 3~5 之间起步,用真实读取模式做基准测试后再调优。