再分析数据的 CF 规范与 Python 工具链

把一份 ERA5 的 NetCDF 文件丢进 Python,你大概率会先撞上一连串问题:变量叫 t2m 还是 tas?单位是 K 还是 °C?时间轴写的是 hours since 1900-01-01 又该怎么解析?辐射字段是瞬时功率还是累积能量?这些看似琐碎的语义歧义,恰恰是风电、光伏、功率预测团队在数据工程阶段最常踩的坑——一个单位换错、一个时间偏移没对齐,下游模型的训练样本就整体污染了。CF(Climate and Forecast)元数据规范,就是为消除这类歧义而生的"语义合同";而 xarray、cfgrib、netCDF4 这套 Python 工具链,则是把这份合同自动执行起来的工具。读懂它们,等于给你的气象数据管线上了一道防错保险。
关键要点
- CF 规范是再分析数据的"语义合同":用
standard_name、units、坐标轴与时间编码,让 NetCDF / GRIB 文件自己说清"自己是什么",机器和人都能无歧义读懂。CF 1.0 于 2003 年 10 月发布,当前主线约 1.13。 - CF 标准名表覆盖超过 1000 个物理量,每个名字都带精确定义与规范单位(canonical units),是跨数据源融合(再分析 + 观测 + 预报)的语义前提。
- xarray、cfgrib、netCDF4 是这套约定的执行引擎:xarray 提供 pandas 式的带标签多维数组操作,cfgrib 经 ecCodes 把 GRIB1/GRIB2 归一到 CF/Common Data Model,netCDF4 负责底层读写。
- 时间与单位是再分析数据最高发的两类错误,CF 的
units + calendar + cell_methods三件套正是标准答案,把"靠经验记换算公式"变成"靠元数据自动执行"。 - 运梦气象 API 返回字段按 CF 口径命名(单位经后处理)(
tas为 ℃、pr为 mm/h、rsds为W m-2;命名是 CF 口径,但温度、降水单位为便于使用已做后处理,与 CF canonical 的K、kg m-2 s-1不同),拿到数据几乎可直接喂进 xarray 管线,省掉重命名这层胶水代码;温度与降水的单位则按上述口径按需换算。
背景与定位
CF 规范的英文全称是 Climate and Forecast (CF) Metadata Conventions,主要编者为 Eaton、Gregory、Drach、Taylor、Hankin 等一批来自美欧气候与天气实验室的研究者,社区维护、开放治理。它的 1.0 版本于 2003 年 10 月正式发布,是在更早的 COARDS(1995 年)与 Gregory/Drach/Tett(GDT)约定基础上的泛化与扩展,至今仍在持续演进(当前主线版本约为 1.13)。
工具链一侧最具代表性的学术引用,是 Hoyer 与 Hamman 于 2017 年发表在《Journal of Open Research Software》上的 xarray 论文。这篇论文把"带标签的 N 维数组 + 自描述科学数据模型"这一思路系统化,让 NetCDF 的多维数据在 Python 里第一次有了像 pandas 一样顺手的操作体验。CF 定标准、xarray 定操作范式,二者一起构成了今天再分析数据处理的事实基石——这也是它们权威且前沿的原因:几乎所有主流再分析产品(ERA5、MERRA-2 等)和 AI 气象大模型的训练数据,都默认按 CF 约定组织。
方法 / 它做了什么
CF 规范本质上是一套写在 NetCDF(以及被移植到 HDF5)文件属性里的命名与编码约定。它解决的核心问题是:让一份数据文件"自己说清楚自己是什么",机器和人都能无歧义地读懂。 具体落在几个关键机制上:
- standard_name 标准名表:CF 维护一张超过 1000 个物理量的标准名词典,每个名字(如
air_temperature、surface_downwelling_shortwave_flux_in_air)都配有精确文字定义和"规范单位"(canonical units)。变量叫什么内部短名无所谓,只要标注了standard_name,跨数据集就能精确对齐同一个物理量。 - units 单位约定:CF 要求单位用 UDUNITS 可解析的字符串(如
K、W m-2、kg m-2),工具据此能自动做量纲检查和换算,避免"K 当成 °C 用"这类灾难。 - 坐标与坐标轴:通过
axis(X/Y/Z/T)、coordinates、bounds等属性,明确每个维度是经度、纬度、高度还是时间,连不规则网格、投影坐标也能描述。 - 时间编码:时间用"
<单位> since <参考时刻>"加calendar属性表达,工具能据此还原成真实日期——这正是hours since 1900-01-01能被自动解析的原因。 - cell_methods 与累积量语义:用
cell_methods标注一个值是瞬时、时段平均还是累积,从根本上区分"瞬时辐照功率"与"累积辐射能量"。
Python 工具链则是这套约定的"执行引擎"。netCDF4(Unidata 出品,底层是 netCDF C 库、构建在 HDF5 之上)负责最底层的读写;xarray 在其上提供带标签的 Dataset/DataArray,按 CF 约定自动解码时间轴、识别坐标、保留单位元数据,并带来类 pandas 的索引、分组、重采样、对齐能力,还能借 dask 做超内存的惰性计算;cfgrib(ECMWF 出品)则把 GRIB1/GRIB2 文件按 CF 约定映射到同一个 Common Data Model,底层调用 ecCodes 解码,一行 engine='cfgrib' 就能让 xarray 像读 NetCDF 一样读 GRIB。于是无论数据来自 NetCDF 还是 GRIB,进到 Python 里都是同一套带 CF 语义的对象,下游代码完全统一。
关键结论
- CF 标准名表覆盖超过 1000 个物理量,每个名字带精确定义与规范单位。这意味着只要两份数据都标了同一个
standard_name,就能在物理量层面安全对齐——这是跨数据源融合(再分析 + 观测 + 预报)的语义前提。 - xarray 把多维气象数据带进了"pandas 式"操作范式(Hoyer & Hamman, 2017):标签索引、自动对齐、按时间分组与重采样、可选 dask 惰性计算。对功率预测团队而言,"取某经纬度、某时间窗、某几个变量"从手写下标循环变成一行声明式调用。
- cfgrib 让 GRIB 与 NetCDF 在 Python 层归一:通过 ecCodes 把 GRIB1/GRIB2 映射到 CF/Common Data Model,
xr.open_dataset(path, engine='cfgrib')即可。在多数评测口径下它能惰性、低内存地读取主流 GRIB 文件,从而省掉一套独立的 GRIB 解析栈。 - 时间与单位是再分析数据最高发的两类错误,而 CF 的
units + calendar + cell_methods三件套正是针对它们的标准答案;只要源数据遵守 CF,xarray/cfgrib 就能自动正确解码,把"靠经验记换算公式"变成"靠元数据自动执行"。需要界定的是:这套自动化以源数据规范标注为前提,遇到标注缺失或非标产品时仍需人工校核。
对新能源 / 运梦平台的意义
把 CF 工具链落到风电、光伏、电网、功率预测的日常,价值非常具体:
- 数据接入零换名负担:风资源评估常用
u100/v100、光伏常用rsds/dni/dhi、负荷关联常用tas/hurs/sp/pr。只要遵循 CF 命名,特征工程代码就不必为每个数据源维护一张"短名 → 业务名"的换算表,减少了大量隐性 bug。 - 单位与时间不再靠人脑:辐射字段究竟是
W m-2(瞬时功率)还是J m-2(累积能量),CF 用units与cell_methods写得明明白白;时间轴的参考时刻与日历由units + calendar自动还原。功率预测最怕的"单位错、时区偏",在源头就被堵住。 - 多源融合有共同语义层:历史回测用再分析、滚动预报用预报场,两者只要都贴合 CF 的
standard_name,就能在同一物理量上无缝拼接,做偏差订正(BC / quantile mapping)时也有统一坐标。 - 管线可重放、可审计:xarray 的
Dataset自带完整元数据,中间产物落盘后仍自描述,便于复盘训练样本来源、满足合规审计。
运梦气象 API 在设计上正是对齐了这套约定:返回字段按公开字段表统一命名(CF 口径),单位与 CF 标准一致(tas 为 ℃、pr 为 mm/h、rsds 为 W m-2;命名是 CF 口径,但温度、降水单位为便于使用已做后处理,与 CF canonical 的 K、kg m-2 s-1 不同),让你从 API 拿到数据后,几乎可以直接喂进按 CF 假设写好的 xarray 管线,省掉重命名这层胶水代码;温度与降水的单位则按上述口径按需换算。
在运梦气象 API 上手
下面用 downloadSync 接口拉一段华东某点 2024 全年、CF 命名的历史字段(历史回测固定用 era5)。返回的 data 里 timeList 与各字段数组按下标一一对应,可直接转成 xarray/pandas 对象继续按 CF 语义处理。
{
"dataSourceId": "era5",
"lat": 31.5,
"lon": 118.5,
"stime": "2024-01-01 00:00",
"etime": "2024-12-31 23:00",
"fields": ["tas", "uas", "vas", "u100", "v100", "rsds"],
"timezone": "8"
}
import os, requests, pandas as pd
API = "https://console.yun-meng.top/api/energy-weather/search/weather/action/downloadSync"
payload = {
"dataSourceId": "era5", # 历史回测用 era5;预报场景改用 ger(德国气象局)
"lat": 31.5, "lon": 118.5,
"stime": "2024-01-01 00:00", "etime": "2024-12-31 23:00",
"fields": ["tas", "uas", "vas", "u100", "v100", "rsds"],
"timezone": "8",
}
resp = requests.post(API, headers={"Authorization": f"Bearer {os.environ['YUNMENG_TOKEN']}"},
json=payload, timeout=600)
resp.raise_for_status()
data = resp.json()["data"]
# 字段已是 CF 命名(rsds=W m-2);注意 tas 为 ℃、pr 为 mm/h(已后处理),按 CF canonical(K) 处理前需换算
df = pd.DataFrame({"time": pd.to_datetime(data["timeList"]),
"tas": data["tas"], "rsds": data["rsds"]}).set_index("time")
# 转 xarray 后即可按 CF 语义重采样、对齐、与预报场拼接
ds = df.to_xarray()
print(ds)
预报场景把 dataSourceId 换成 ger(德国气象局,未来约 7 天),其余字段约定不变;历史与预报因同遵 CF 命名,可在同一管线里无缝衔接。完整字段定义见 数据要素解释,产品规格见 ERA5 产品页,更多数据工程避坑可参考 气象数据工程的常见陷阱。
常见问题
CF 规范到底是什么?它解决什么问题?
CF(Climate and Forecast)元数据规范是一套写在 NetCDF(及移植到 HDF5)文件属性里的命名与编码约定,核心目标是让一份数据文件"自己说清楚自己是什么"。它通过 standard_name、units、坐标轴与时间编码,消除变量短名、单位、时间轴、瞬时与累积等语义歧义,机器和人都能无歧义读懂。
用 Python 读再分析数据该用哪个库?xarray、cfgrib、netCDF4 怎么选?
三者各司其职:netCDF4 负责最底层的 NetCDF 读写;xarray 在其上提供带标签的 Dataset/DataArray,按 CF 约定自动解码时间轴、识别坐标、保留单位元数据,并带来类 pandas 的索引、分组、重采样能力;cfgrib 则把 GRIB1/GRIB2 按 CF 约定映射到同一 Common Data Model,让 xarray 用 engine='cfgrib' 像读 NetCDF 一样读 GRIB。
为什么 ERA5 的时间轴写成 hours since 1900-01-01,xarray 能自动解析?
因为 CF 用"<单位> since <参考时刻>"加 calendar 属性来表达时间,工具据此能把数值还原成真实日期。这正是 hours since 1900-01-01 能被自动解析的原因,前提是源数据规范标注了 CF 时间属性。
怎么区分辐射字段是瞬时功率还是累积能量?
看 units 与 cell_methods:W m-2 表示瞬时辐照功率,J m-2 表示累积能量;cell_methods 进一步标注一个值是瞬时、时段平均还是累积。CF 把这一区分写在元数据里,从根本上避免把瞬时功率当成累积能量误用。
运梦气象 API 返回的数据需要重命名或换单位吗?
基本不需要。运梦气象 API 返回字段按公开字段表统一用 CF 口径命名,单位也与 CF 标准一致(tas 为 ℃、pr 为 mm/h、rsds 为 W m-2;命名是 CF 口径,但温度、降水单位为便于使用已做后处理,与 CF canonical 的 K、kg m-2 s-1 不同),拿到数据后几乎可以直接喂进按 CF 假设写好的 xarray 管线,省掉重命名这层胶水代码;温度与降水的单位则按上述口径按需换算。
引用与原文
- Eaton, B., Gregory, J., Drach, B., Taylor, K., Hankin, S., et al. (2003, 持续更新). NetCDF Climate and Forecast (CF) Metadata Conventions. CF Conventions(初版 1.0 于 2003 年 10 月发布,当前主线约 1.13). https://cfconventions.org/
- Hoyer, S., & Hamman, J. (2017). xarray: N-D labeled Arrays and Datasets in Python. Journal of Open Research Software, 5(1), 10. https://doi.org/10.5334/jors.148
- ECMWF. cfgrib: A Python interface to map GRIB files to the NetCDF Common Data Model following the CF Convention using ecCodes. https://github.com/ecmwf/cfgrib
- Unidata. netcdf4-python: Python/NumPy interface to the netCDF C library. https://unidata.github.io/netcdf4-python/