一、什么是 netCDF
netCDF(Network Common Data Form)是一种用于存储和共享面向数组的科学数据的文件格式,广泛应用于气象、海洋、地球科学等领域。文件扩展名通常为.nc。
netCDF 数据中存储三种核心数据:
| 数据类型 | 说明 | 类比 |
|---|---|---|
| 维度(Dimension) | 描述数据的坐标轴信息,如经度、纬度、时间、高度 | 类似函数中的自变量 |
| 变量(Variable) | 由一个或多个维度组成的数据数组 | 类似函数的函数值 |
| 属性(Attribute) | 对维度和变量的描述信息,如单位、缺测值 | 类似自变量和函数值的单位标注 |
用函数来类比:
v = f(x, y, z) │ └──┬──┘ │ └── 维度:x(经度), y(纬度), z(时间) └── 变量:如降水量、温度等 └── 属性:单位(kg/m²)、缺测值(9999)等二、netCDF 解决了什么问题
传统 GeoTIFF 格式存储的是二维栅格数据,无法原生描述时间维度。要表示多个时间步的数据,需要多个.tif文件,且时间信息只能靠文件名约定来携带。
netCDF 通过维度定义数据的坐标轴(经度、纬度、时间、高度等),变量存储实际数据,天然支持多维时空数据的组织与查询,便于进行时空分析。
# GeoTIFF 方式:多个独立文件,时间靠文件名约定 precip_2026060800.tif precip_2026060801.tif precip_2026060802.tif ... # netCDF 方式:一个文件内含完整时空数据 precip.nc ├── 维度: lat(321), lon(411), time(24) ├── 变量: precipitation(lat, lon, time) └── 属性: units="kg/m²", _FillValue=-9999三、netCDF 文件的内部结构
一个 netCDF 文件的逻辑结构如下:
netCDF 文件 ├── 维度 (Dimensions) │ ├── lat_0 — 纬度轴,321 个点 │ ├── lon_0 — 经度轴,411 个点 │ └── time — 时间轴(可选) │ ├── 变量 (Variables) │ ├── lat_0(float) → 属性: units, axis │ ├── lon_0(float) → 属性: units, axis │ └── APCP_P0_L1_GLL0(float, dim=[lat_0, lon_0]) │ └── 属性: units="kg m-2", _FillValue=-9999 │ └── 全局属性 (Global Attributes) ├── Conventions ├── history └── institution3.1 维度(Dimension)
维度定义了数据在每个方向上的大小。每个维度有一个名称和一个长度。
- 坐标变量(Coordinate Variable):与维度同名的变量,存储该维度的具体取值。例如维度
lat_0有 321 个点,对应的坐标变量存储了38.0, 38.05, 38.10, ..., 54.0的具体纬度值。
3.2 变量(Variable)
变量是 netCDF 中的核心数据载体,由一个或多个维度组成。
示例:APCP_P0_L1_GLL0(累计降水量) 形状:(321, 411) —— 即 321 行 × 411 列的二维数组 维度:lat_0 × lon_0 含义:某一时刻,每个网格点上的降水量变量的命名通常来自数据生产方的约定,例如 GRIB 格式转换而来的APCP_P0_L1_GLL0表示"累计降水(Accumulated Precipitation)"。
3.3 属性(Attribute)
属性是键值对形式的元数据,用于描述维度、变量或整个文件。
| 属性位置 | 示例键 | 示例值 | 说明 |
|---|---|---|---|
| 变量属性 | units | "kg m-2" | 数据单位 |
| 变量属性 | _FillValue | -9999 | 缺测填充值 |
| 变量属性 | long_name | "Total precipitation" | 变量的可读名称 |
| 全局属性 | Conventions | "CF-1.6" | 遵循的元数据规范 |
四、在 Python 中解析 netCDF
Python 中一般使用xarray库解析 netCDF 文件。
4.1 基本读取
importxarrayasxr ds=xr.open_dataset("precip.nc")print(ds)xr.open_dataset()将 netCDF 文件读取为Dataset对象,包含以下组成部分:
| 组成部分 | 说明 | 对应关系 |
|---|---|---|
Dimensions | 维度名称及其大小 | 直接对应 nc 文件中的维度定义 |
Coordinates | 维度的具体取值 | 对应坐标变量存储的值 |
Data Variables | 数据变量(多维数组 + 维度绑定 + 坐标信息 + 自身属性) | 对应 nc 文件中的非坐标变量,每个变量是一个DataArray对象 |
Attributes | 全局属性键值对 | 对应 nc 文件的全局属性 |
4.2 查看数据结构
# 查看维度信息print(ds.dims)# Frozen({'time': 24, 'lat_0': 321, 'lon_0': 411})# 查看坐标值print(ds.coords)# Coordinates:# * lat_0 (lat_0) float32 38.0 38.05 38.1 ... 53.95 54.0# * lon_0 (lon_0) float32 115.0 115.05 ... 135.45 135.5# 查看变量print(ds.data_vars)# Data variables:# APCP_P0_L1_GLL0 (time, lat_0, lon_0) float32 ...# 查看变量属性print(ds["APCP_P0_L1_GLL0"].attrs)# {'units': 'kg m-2', 'long_name': 'Total precipitation', ...}4.3 数据选取与切片
# 选取某个变量precip=ds["APCP_P0_L1_GLL0"]# 按时间切片precip_t0=precip.isel(time=0)# 按索引选取第 0 个时间步precip_sel=precip.sel(time="2026-06-08")# 按标签选取(按坐标的实际值,如 2026-06-08 这个时间点)# 按空间范围裁剪precip_region=precip.sel(lat_0=slice(38.0,54.0),lon_0=slice(115.0,135.5))# 转为 NumPy 数组arr=precip_t0.values# shape: (321, 411)4.4 数据清洗
实际业务中,netCDF 数据常包含缺测值或异常值,需要在使用前清洗:
importnumpyasnp# 方式一:通过 _FillValue 自动处理ds=xr.open_dataset("precip.nc")# xarray 会自动将 _FillValue 替换为 NaN# 方式二:手动处理特定缺测值(如 9999 不是标准 _FillValue 时)precip=precip.where(precip!=9999)# 9999 → NaNprecip=precip.where(precip>=0,0)# 负值误差 → 0precip=precip.fillna(0)# NaN → 0(适用于累计场景)注意:在本项目的降水数据中,
9999大量出现但并非_FillValue,必须手动处理,否则累计计算会被严重污染。
4.5 关闭文件
ds.close()# 或使用 with 语句自动关闭withxr.open_dataset("precip.nc")asds:precip=ds["APCP_P0_L1_GLL0"].values五、netCDF 与其他格式的对比
| 特性 | netCDF (.nc) | GeoTIFF (.tif) | HDF5 (.h5) | GRIB |
|---|---|---|---|---|
| 多维数据 | 原生支持 | 仅 2D | 原生支持 | 原生支持 |
| 时间维度 | 原生支持 | 不支持 | 需自行组织 | 原生支持 |
| 自描述元数据 | 有 | 有限 | 有 | 有 |
| 跨平台 | 是 | 是 | 是 | 是 |
| 生态支持 | Python/Fortran/C | GDAL/QGIS | Python/C | 较专用 |
| 压缩 | 支持 | 支持 | 支持 | 支持 |
| 典型场景 | 气象/海洋/气候 | 遥感/GIS | 科学计算 | 气象预报 |
六、常见 netCDF 变量命名约定
6.1 CF 命名规范(Climate and Forecast)
遵循 CF 规范的 netCDF 文件使用标准化的变量名和属性名:
| 变量名 | 含义 | 单位 |
|---|---|---|
pr | 降水率(Precipitation Rate) | kg m-2 s-1 |
prc | 对流降水率 | kg m-2 s-1 |
tas | 近地面气温 | K |
uas | 近地面 U 风速 | m s-1 |
vas | 近地面 V 风速 | m s-1 |
psl | 海平面气压 | Pa |
6.2 GRIB 转换命名
从 GRIB 格式转换而来的 netCDF 文件通常保留 GRIB 风格的命名:
| 变量名 | 含义 |
|---|---|
APCP_P0_L1_GLL0 | 地面累计降水(Accumulated Precipitation) |
TMP_P0_L1_GLL0 | 地面温度(Temperature) |
UGRD_P0_L1_GLL0 | U 方向风速 |
VGRD_P0_L1_GLL0 | V 方向风速 |
坐标变量也可能命名为lat_0/lon_0而非标准的lat/lon。
七、参考资源
- 【python】xarray(1): netCDF(NC)格式解读与读取 - 知乎](https://zhuanlan.zhihu.com/p/393392465)