逐日海温 OISST v2.1 — 四十五年,一天不缺的全球海面

542 个月、16,493 个日文件、27.4 GB,一张 0.25° 的逐日海温网与它的三段版本史

来源 NOAA National Centers for Environmental Information(NCEI) url: https://www.ncei.noaa.gov/products/optimum-interpolation-sst发布时间: 2026-10-29最后更新: 2026-10-29 阅读 8
逐日海温 OISST v2.1 — 四十五年,一天不缺的全球海面

信息速览

数据集名称逐日海温 OISST v2.1 — 四十五年,一天不缺的全球海面
数据类型1981-09 至今逐日,0.25° 全球格点,720×1440,四变量 sst/anom/err/ice,16,493 个日文件,27.4 GB,终版 15 天延迟,公有领域
规模不适用(全球海温格点场,无个体记录;空间单位为经纬度格心,时间单位为日)
接入方式NOAA National Centers for Environmental Information(NCEI) url: https://www.ncei.noaa.gov/products/optimum-interpolation-sst
AI 就绪度

OISST 是海洋机器学习里那块最不起眼的底板:想要某片海某一天有多热,几乎都会先打开它。它的分量不在分辨率,而在于把 1981 年 9 月以来的每一天,压成了同一张 720×1440 的网格、同一套处理链、同一个文件格式。

它同时是「输入的原料」和「答案的标尺」。预测海温的模型拿它当训练目标,做海洋热浪、珊瑚白化、渔业资源评估的项目拿它当判定依据。这两件事共用同一份数据,也正是大量结论无法外推的根源。

这份条目只讲 v2.1 的 AVHRR-only 逐日 0.25° 产品——不是 1° 周平均的老 OI.v2,也不是 2002 至 2011 年那段加微波的组合产品。一屏速览见下表。

项目 数值 来源
官方全名 NOAA 0.25-degree Daily OISST, Version 2.1 DOI 元数据页标题
制作方 NOAA/NCEI,CDR 计划,首席研究员 Boyin Huang CDR 产品页
时间覆盖 1981-09-01 至 2026-10-27,逐日 目录索引逐月清点
空间网格 0.25°×0.25°,720 纬 × 1440 经 文件坐标变量
每文件变量 sst、anom、err、ice 四个 文件结构
单文件体积 中位 1.68 MB(1.49–1.76 MB) 目录索引 Size 列
全量 542 个月 / 16,493 个文件 / 27.43 GB 目录索引逐月求和
容器 NetCDF-4(HDF5),int16 打包 _NCProperties 属性
更新 逐日;未定版 1 天,终版约 15 天 文件 summary 属性
许可 公有领域,无 SPDX 标识 CDR 使用协议 PDF
DOI 10.25921/RE9P-PT57 DOI 解析至 C01606
访问门槛 无注册,HTTP 与 S3 均可匿名访问 目录可直接列出

§1 速览:它是什么,也不是什么

§1.1 一句话定义

OISST v2.1 是一张每天一张、全球海洋、0.25 度一格的海温图,由 NOAA 把卫星、船舶、浮标、Argo 四种来源的观测按最优插值的方法融合而成,从 1981 年 9 月 1 日起一天一个文件,至今没有断过。

它不是卫星原始影像,不是浮标的定点读数,也不是一份「观测记录」。每一格的值都是解出来的:观测落进网格,缺的地方由插值补上,补的方式受误差协方差约束。所以它处处有值——包括那天没有任何仪器经过的海域。

§1.2 为什么它不是「又一份海温产品」

第一层原因是混合的比例是可变的。1981 年靠的是几条 NOAA 极轨卫星上的 AVHRR 加商船报;2020 年代靠的是 MetOp 系列加更密的浮标网与 Argo。同一张网格背后,观测平台换过好几代,而产品名一直叫 OISST v2.1。这意味着「1982 年的格点」和「2024 年的格点」不是同一种东西,尽管它们在文件里长得一模一样。

第二层原因是它自己就是一条链。翻开源码文档会看到一句很容易被忽略的话:这份分析的初猜(first guess)是前一天的分析结果。于是第 N 天不是从零算起的,它继承了第 N−1 天的场。这个设计让逐日的场在时间上平滑,也让「把日文件当成独立样本」这件事从根上不成立。

第三层原因是它的元数据比数据更容易骗人。文件自带的 title 属性会被截到 110 个字符,未定版那一份的结尾停在「- Inter」;全局属性写纬度范围 -90 到 90,坐标变量却是 -89.875 起;有一个叫 zlev 的维度,属性写着「海面高度、单位米」,实际恒为 0。这些都无害,但每一条都能让写脚本的人多花半天。

§1.3 三十秒决策卡:你的处境,它能帮你什么

你的处境 它能帮你什么
要训练一个逐日海温预测或补缺模型 四十五年逐日、全球同网格、口径一致的场,训练与验证可取自同一套,缺日为零
要判定某年某海域是否发生海洋热浪 距平场已按 1971–2000 气候态算好,阈值法可以直接用,不用自己建气候态
要给渔业、养殖、珊瑚监测配一份环境背景 逐日 0.25°,覆盖全部海域,匿名可下,成本近乎为零
要做海气耦合或卫星产品的交叉验证 与微波、红外观测的独立性足够,常被当作参照场
要研究近岸、海湾、养殖区尺度的水温 给不了,见下一节
要做逐小时或公里级的海洋预报 给不了,时间步长是一天,格距是几十公里

§1.4 不适合谁

如果需求是近岸与半封闭水域,这份数据会误导。0.25° 一格在赤道约 27.8 公里,在 40°N 约 21 公里;一个海湾、一片养殖区往往不足一格。近岸格点里同时含有陆地与浅海,值是整格的平均,而陆地部分是被掩膜掉后用邻域插出来的。用它判断「我这一片筏架今天水温多少」,误差可以大到改变结论。

如果需求是逐小时变化,它也给不了。一天只有一个时刻(UTC 正午),日内潮汐、日较差、夜间降温全部被平均掉。要小时级,得去看现场浮标、高频雷达或区域模式。

如果需求是未经平滑的观测,同样不合适。这是分析场,插值的目的就是填洞,填出来的值与「那里真实的水温」不是一回事。误差场能告诉你哪里的填补更不可信,但它不改变「处处有值」这一事实。

如果需求是跨 2016 年的严格同质序列,需要额外处理。2016 年 1 月 1 日起 v2.1 换了现场观测的来源、加了 Argo、换了卫星输入、改了冰转换方法,四件事同时发生。前后两段并非同一套处理规则,做长期趋势时必须交代这一点。

§2 数据构成:一天一个文件,四个变量,两维半

§2.1 全量规模:哪些是官方口径,哪些是数出来的

官方页只给了一句话:1981 年 9 月 1 日至今、逐日、0.25°、每日更新。目录里的实际体量没有任何页面写,只能自己数。

维度 数值 怎么得到的 性质
月目录数 542 顶层索引计数,198109 至 202610 目录
日文件数 16,493 逐月索引求和 目录
其中未定版 14 文件名含 _preliminary 目录
覆盖天数 与文件数相同 1981-09-01 至 2026-10-27 的天数 推算
总体积 27.43 GB 逐月 Size 列求和,27,433,714,184 字节 目录
单文件中位 1.68 MB 同上,中位数 1,676,973 字节 目录
单文件范围 1.49–1.76 MB 同上,最小 1,489,788、最大 1,761,991 目录
每变量格点数 1,036,800 720×1440 文件形状
每日数值个数 4,147,200 四变量 × 格点数 推算
全量数值个数 约 684 亿 上项 × 天数 推算

两个数字值得单独说。

一个是覆盖天数与文件数完全相等。1981-09-01 到 2026-10-27 是一万六千四百九十三天,目录里也是一万六千四百九十三个文件,未定版的十四个各自占着一个还没出终版的日期。也就是说这份数据四十五年没有缺过一天。这一点不靠信任:把顶层索引的 542 个目录名念一遍,把每月文件数加一遍,两个数自然对上。

顺带说清「不缺一天」这句话的边界。它说的是日期完整,不是每天都有效。二十世纪八十年代的南大洋、北极边缘,很多格点在那一天没有任何观测进入分析,值是插出来的。文件不缺、格点不缺,缺的是「这一天这一格的结论有多可靠」——那件事由 err 场承担,不是由文件名承担。

另一个是体积不能用单一样本外推。最早那一批 1981 年的文件是 1.71 MB 左右,2026 年的文件是 1.51 MB 左右,极差接近 18%。按 1.71 MB 乘 16,500 天会得到 28 GB 出头,比真实的 27.43 GB 高估约 3%。做容量规划时按中位数 1.68 MB 算,误差在一两个百分点以内。

§2.2 一个文件里到底有什么

文件是 NetCDF-4 容器(HDF5 底层,_NCProperties 写作 version=2,netcdf=4.8.1,hdf5=1.12.1),sst、anom、err、ice 四个数据变量都做了 gzip 压缩加 shuffle 预调。

变量 形状 存储类型 物理量 属性域 填充值
sst (1, 1, 720, 1440) int16 日海表温度 -3.00 至 45.00 °C -999
anom (1, 1, 720, 1440) int16 距平 -12.00 至 12.00 °C -999
err (1, 1, 720, 1440) int16 误差标准差 0 至 10.00 °C -999
ice (1, 1, 720, 1440) int16 海冰密集度 0 至 100 % -999
time (1,) float32 当日中心时刻 标量 无
zlev (1,) float32 恒为 0 的伪维度 0 无
lat (720,) float32 纬度格心 -89.875–89.875 无
lon (1440,) float32 经度格心 0.125–359.875 无

四个数据变量共用 scale_factor = 0.01、add_offset = 0。也就是说存进去的整数 1832 表示 18.32 °C,整数 -999 表示没有值。忘记乘这个系数,会读出一片几千度的海。

属性域那两栏是从 valid_min 与 valid_max 换算来的,不是猜的:sst 写作 -300 与 4500,anom 写作 ±1200,err 写作 0 与 1000。它们同时说明了这份数据的硬边界——它不接受低于 -3 °C 或高于 45 °C 的海温,超出就钳在这里。

§2.3 四个变量不是四份观测

初学者常把四个变量当成四种测量,其实它们是一份分析的四张面孔。

sst 是主角,最优插值的输出。anom 是同一天的 sst 减去气候态,气候态取自 1971–2000 年的 OI.v2,由 1° 月产品插值到这张 0.25° 的日网格上。err 是这次分析自己估的误差标准差:一部分来自 OI 的随机与采样误差,一部分来自偏差订正后的残余误差。ice 是海冰密集度,取的是 7 天中值而不是当日值;它在冰缘带被换算成代理海温,用来把开阔海域的温度插值一直推到季节性冰缘。

四者的关系可以用一句话概括:sst 是结果,anom 是结果减背景,err 是结果的自我评价,ice 是结果在冰区的替代品。读懂这一句,就不会问「为什么 anom 和 sst 高度相关」这种问题——它们当然相关,差的只是一个随经纬度和日期变化的气候态。

顺带说一个口径问题。官方 CDR 页的「CDR Variables」只列了三项:海表温度、海面高度、海冰密集度。距平与误差被归到「Additional Data」里,是配套地图而非 CDR 变量。引用时把 anom 说成「CDR 定义的变量」在措辞上不严谨,尽管它在文件里与 sst 平级。那个「海面高度」正是 zlev 这个空维度的来源。

§2.4 一条格点记录的逐项解剖

取 2026-10-13 那份终版文件,看北太平洋副热带上某个格点:

层面 内容 要注意什么
索引 sst[0, 0, 450, 630] 四维下标,前两维恒为 0
纬度 450 × 0.25 − 89.875 = 22.625°N 升序,北在数组末尾
经度 630 × 0.25 + 0.125 = 157.625°E 0 度在列首,无负经度
时间 当日 UTC 正午 units 的 1978 纪元与数据无关
存储值 2913 int16 原始值
物理值 29.13 °C 乘 0.01
填充 -999 陆地、无分析结果都长这样
单位 Celsius 属性里写的是全称,不是 °C

这张表里最容易被忽略的是第三行和最后两行。时间轴的单位写着「1978 年 1 月 1 日 12 时起的天数」,1978 只是 NCEP 网格模板的纪元常数,数据并不从 1978 年开始——把纪元当起点,会把整条时间轴往前挪三年多。单位那一行看似琐碎,实际会影响自动化管线:按 units == "degC" 做字符串匹配的代码,在这里会匹配失败。

§2.5 空间与时间的边界

格心与格边差半格。 坐标变量给的是格心,-89.875 到 89.875、0.125 到 359.875;全局属性给的是包络,-90 到 90、0 到 360。前者是点,后者是边。用后者当栅格范围去配准,整幅图会平移半格——在 0.25° 的尺度上就是十几公里。做 GIS 叠置之前必须确认用的是哪一套。

经度没有负值。 数组从 0.125°E 排到 359.875°E,跨日界线的区域(比如从 170°E 到 170°W)会被切成数组的两端。任何按经度切片再求平均的脚本,如果不做滚列,得到的是两段相隔半个地球的海。

纬度越高,格子越窄。 0.25° 在赤道约 27.8 公里,40°N 约 19.7 公里,60°N 约 13.9 公里。做全球平均、算热含量、统计某一纬度带的面积占比,都必须乘纬度余弦,否则高纬会被系统性高估——这不是精度问题,是数量级问题。

zlev 是一个幽灵维度。 它的 long_name 写着「Sea surface height」,units 是米,positive 是 down,而 actual_range 是 0 到 0。它存在的唯一理由是这套网格模板天生四维。用 xarray 打开会看到 (time: 1, zlev: 1, lat: 720, lon: 1440),用裸数组读会拿到四维 ndarray。写 sst[0] 得到的是三维,写 sst[0, 0] 才是二维——两者都对,但混用会在拼接时炸出形状错误。

时间不是轴,是链。 这是全篇最重要的一条边界,值得单独一节展开,见 §4.1。

§2.6 与同类资源的定位差异

资源 核心内容 与 OISST v2.1 的差别
1° 周平均 OI.v2 1970 年代起的周平均,1° 网格 时间与空间都粗一档;不是把日产品做七天平均得来的,插值前就已聚到 1°
AMSR+AVHRR 组合 微波加红外,2002–2011 微波不受云影响、开阔洋面更准,但只覆盖九年,且已于 v2 时代结束
ERA5 的海表温度 再分析场里的海温 来自海洋模式的同化,时间平滑、物理自洽,但把它当观测用会低估极值
现场浮标 单点逐小时 真值性质最好,但只有点,无空间覆盖,且分布极不均匀
卫星 L3 级海温 单星反演,逐日 有云就有洞,未做插值填补;OISST 正是拿这类产品当输入

判断规则可以压成一句:要全球、逐日、无洞、长序列 → OISST;要单点真值 → 浮标;要物理自洽的多要素场 → 再分析;要看单星原始反演 → L3。

§3 定位层:先分清「哪一个 OISST」

§3.1 一个名字,四条产品线

「OISST」在文献里至少指四样不同的东西,混用会直接导致数字对不上。

名称 分辨率 时间 状态
1° 周平均 OI.v2 1° 1981 年起,周 2022-12-05 起 NCEP 侧停止
0.25° 逐日 v2 0.25° 1981-09 起 2020-04-26 停产,被 v2.1 取代
0.25° 逐日 v2.1 0.25° 1981-09 起 现役,逐日更新
AMSR+AVHRR 组合 0.25° 2002–2011 随 v2 结束,现由 THREDDS 侧保留

四条线里被引用最多的是第三条,也就是本篇的对象。第一条容易被误当成「日产品的周平均」,官方 FAQ 专门澄清过:周产品是把一周的卫星观测先在 1° 网格上平均、再做插值,不是对 0.25° 日产品做时间平均。两者不能互相推导。

§3.2 v2.1 与 v2 的真实差别

2020 年 4 月 1 日 v2.1 顶替 v2,v2 在 4 月 26 日停止生产。但「换版」这件事并不像版本号暗示的那样整齐。

官方页写得很清楚:2016 年 1 月 1 日之后的数据有实质质量改进,此前的数据与 v2 相同——只是从 NetCDF-3 换成了 NetCDF-4,并更新了元数据。文件里的 comment 属性补了时间点:这次容器转换发生在 2017 年 11 月。

于是同一份 v2.1 里其实躺着两段历史:2016 年前是「换了包装的 v2」,2016 年后才是真正的新算法。做跨 2015/2016 的分析时,先确认自己比较的是数据还是包装。

§3.3 三个版本号写在同一句话里

产品名是 v2.1,文件名里是 v02r01,页面正文里还会出现 v2.1a 与 v2.1b。这三个词指的不是同一层东西。

标记 含义 时间 影响范围
v2.1 / v02r01 产品版本与文件命名 2020-04 起 全序列
v2.1a 卫星海温输入由 Navy 换成 NOAA ACSPO 2021-10-01 起 仅前向生产
v2.1b 船舶偏差订正由常数改为逐月时变 2023-04-01 起 仅前向生产

关键在于「仅前向生产」这四个字。v2.1a 是因为 MetOp-A 退役,ACSPO 能同时吃 AVHRR 与 VIIRS;v2.1b 是因为船测偏差随时间漂移。两次改动都只对改动之后的日子生效,此前的历史没有重算。所以序列里存在两处台阶:2021 年 10 月前后,卫星源换了;2023 年 4 月前后,船测订正方法换了。

这两处台阶不像 2016 年那次有官方大张旗鼓的说明,它们藏在「Product Update History」的小节里。做 2021 或 2023 年前后的趋势比较,如果不查这一节,会把处理规则的切换读成海洋的变化。

§3.4 名字、文件名与唯一指认

唯一可靠的键是文件名:oisst-avhrr-v02r01.YYYYMMDD.nc,未定版加 _preliminary。日期是 UTC 日,与文件内 time 一致。

文件内的 title 属性不能当键用。终版写的是「… Version 2.1 - Final」,未定版写的是「… Version 2.1 - Inter」——Interim 被硬截断在第 110 个字符上,五个字母只剩三个半。用 title.endswith("Final") 判断尚可,用完整字符串做精确匹配必然失败。

第二条陷阱是排序。文件名里的日期是定长的八位数字,字典序即时间序,这一点比很多数据集友好。但目录按月分,202610 与 20261 不会同时出现,跨月拼接时按「目录名 + 文件名」二级排序才安全。

§3.5 final 与 preliminary 不是两条流

很多二手介绍会写「这个产品有 final 和 preliminary 两条数据流」。这个说法会把人带偏。

v2.1 的 access 下只有一个 avhrr 目录,没有 final/、没有 preliminary/。两者同处一地,靠文件名后缀区分。一天的数据先生成未定版(延迟 1 天),约 15 天后被同名去掉后缀的终版覆盖。覆盖之后,未定版在原路径上就不存在了。

覆盖发生的那一刻,内容也变了。文件里的 history 属性写明:终版以未定版为初猜,再补三天的 AVHRR 数据重算;未定版只用一天的数据。所以这不是「同一个东西换个名字」,而是两次不同的计算。

真正需要当心的是云端。AWS 的镜像里,data/v2.1/avhrr/202610/ 这个前缀下同时躺着 20261001.nc 与 20261001_preliminary.nc 两份;历史月份则只有一份、零个未定版。也就是说,未定版在云上没有立刻被删,而是在几天后被清掉。任何按 *.nc 通配去扫前缀的脚本,在最近这半个月里都会把同一天数两遍。这一点在 §5.6 单独给检查办法。

§4 质量层:它最容易被误用的四个地方

§4.1 逐日递归:第 N 天不是独立样本

这是全篇最该记住的一句:每一天的分析,以上一天的分析作为初猜。

算法文档在定义符号时写得很直白:增量是相对于「第一猜参考系」的差,而这份产品的一猜就是前一天的 analysis。产品逻辑上这很合理——海温在一天之内不会跳变,用昨天当起点能压掉噪声。

后果有三个层面。

物理层面,误差在时间上相关。今天的插值误差会带进明天的初猜,于是连续几天的异常可能是一段被平滑过的同一个信号,而不是几次独立的事件。

统计层面,样本不独立。把四十五年的日文件打乱做训练与测试划分,等于让模型在同一条马尔可夫链上前后偷看;随机切分得到的精度会高于按年、按块切分,而后者才反映真实外推能力。

工程层面,重算很贵。想改某一天的算法,不能只重跑那一天——后面所有日子都以它为起点。这也解释了为什么官方对 v2.1a、v2.1b 这类改动一律「只前向、不回溯」:回溯等于重跑整条链。

§4.2 贯穿案例:某海水养殖区的热浪预警(本案例)

后面几节会反复回到这个场景,先把来龙去脉交代清楚。

一支给海水养殖做风险服务的团队,要给北纬 38° 附近一片约 30 公里见方的筏式养殖区做夏季高温预警。他们手上只有两样东西:2018 年才布设的一台浮标,测表层水温,逐小时;以及养殖企业 2019 年以来的损失记录——哪几天出现了大面积死亡。

预警要覆盖 2019 年以前的年份,而浮标那时还不存在。于是他们打算用 OISST 补:先用 2018 年至今的浮标与同格点的 OISST 做一次配对,看偏差有多大;再用 OISST 的距平场定一个阈值(比如超过 90 分位连续五天),回溯到 1982 年,看看历史上这类事件多久发生一次。

方案听起来顺理成章,实际会依次撞上四堵墙。第一堵是格点与养殖区不是一回事(§2.5 与 §4.3);第二堵是距平的基准期不是他们以为的那个(§4.4);第三堵是 2016 年与 2021 年的两处台阶会污染「历史上多久一次」的统计(§4.5);第四堵是误差场不能当置信区间用(§4.6)。四堵墙分别落在下面四小节,每一节末尾都会回到这个团队。

先说第一堵的轮廓:养殖区 30 公里见方,在 0.25° 网格上只落到一到两个格点,而这两个格点里都有陆地。格点值是整格的平均,还掺了掩膜后的插值。团队第一次把浮标与格点画在同一张图上,发现夏季偏差能到 1.5 °C,冬季反而接近零。这不是产品错了,是空间代表性差异在暖季被放大。

§4.3 -3 到 45 的硬截断与 -999 的三种含义

sst 的 valid_min 与 valid_max 是 -300 和 4500,换算过来就是 -3 °C 与 45 °C。这是打包格式与质量控制的联合产物:低于海冰形成温度的开放海水在物理上罕见,高于 45 °C 的表层水温也不存在。落在域外的值会被钳到边界上。

于是有一个反直觉的推论:你读到的 -3.00 与 45.00 可能是钳位,不是测量。极地边缘容易贴上 -3 的下界,封闭浅海在盛夏容易贴上 45 的上界。做极值统计时,把这两端当成真实观测会低估尾部。

填充值 -999 承担了三种完全不同的含义:陆地、无有效分析结果的格点、以及被质量控制剔除的格点。文件里没有字段区分它们。想区分只能自己造掩膜——比如用 ice 是否大于零判断冰区,用地表掩膜判断陆地。这正是 §5.5 里那几行校验代码存在的理由。

回到 §4.2 的团队:他们最初的筛选逻辑是「去掉 -999」,结果把冬季结冰的养殖区格点也一起删了。后来改成「保留 ice > 0 的格点,只用 sst」,才把冬季样本救回来。这个改动让他们多出三个月的可用序列,也让阈值法在冬季有了对照组。

§4.4 距平的基准期是 1971–2000

这是跨产品比较时最常见的错位来源。

OISST 的 anom 用的气候态是 1971–2000 年,来自 OI.v2 的月产品,插值到 0.25° 日网格。文件 references 属性里明写「Climatology is based on 1971-2000 OI.v2 SST」。

而 2020 年代之后新出的很多海温产品、很多海洋热浪研究,习惯用 1991–2020 作基准。两个基准之间,全球平均海温差了约零点几度。于是同一片海、同一天,「距平」在两个体系里能差出半个标准差——足以让「是否超过 90 分位」的判断翻转。

处理办法只有两个:要么统一到 1971–2000,要么放弃 anom 字段,自己用 sst 重建气候态。后者更干净,代价是得把四十五年重算一遍。

§4.2 的案例在这里又撞了一次:他们一开始直接拿 anom 的 90 分位当阈值,后来发现与合作方(用的是 1991–2020 基准的分析产品)给出的「热浪日」对不上,差了将近三成。改法是把两边的 sst 都取出来,用同一段 1982–2011 自建气候态,重新算距平。工作量不大,但这一步不做,两家的预警会永远互相矛盾。

§4.5 误差场不是置信区间

err 的 long_name 写的是「Estimated error standard deviation of analysed_sst」,即估计的误差标准差。它由两部分合成:OI 的随机与采样误差,以及偏差订正后的残余误差。

这意味着三件事。它是一格一个数的标量场,不是一格里的一条分布;它是模型估的,不是与真值比出来的;它只反映「这次插值有多不确定」,不反映「观测本身偏了多少」。

算法文档给了几个能把这件事说实的参数:偏差订正用 130 个经验正交模态,在 2° 网格上求解后插回 0.25°;求解窗口是当天前后各 7 天共 15 天;模态权重再经 5 天二项滤波平滑;最优插值的搜索半径 400 公里,每格最多取 22 个超级观测。

这几个数的组合说明了一件事:在观测稀疏的海域,误差场会大,但那不是「知道得少」,而是「插出来的东西占了大头」。南大洋与北极周边是典型,官方在算法文档的局限一节里也直说,偏差订正依赖现场观测,没有现场观测的地方(尤其极区)不可靠。

实践里的用法是阈值筛:err 超过某个值(比如 0.5 °C)的格点直接剔除,或者按 1/err² 加权。把它当成 95% 置信区间去画误差棒,是把标准差当成了分位数。

§4.6 传感器同质性:一条被写进假设的妥协

算法文档的「传感器性能」一节有一句很重的话:OI 假设 1981 年至今所有 AVHRR 具有相同的统计特性,例如相同的信噪比。

这句话是整条序列能够拼起来的前提,也是一个已知的妥协。AVHRR 从 /2 升级到 /3,搭载平台从 NOAA 系列换到 MetOp 系列,定标方式、过境时刻、通道响应都在变;2021 年后输入还混进了 VIIRS。产品层面用偏差订正把这些差异压到可接受的范围,但「压到可接受」不等于「没有」。

同一节还写着另一句:代码不是为通用卫星写的,每换一颗星都要改代码。这句话解释了为什么 v2.1a 的切换要等到 MetOp-A 退役才做——不是不想早换,是改一次代码要重新验证整条链。

对使用者而言,这条假设的意义是:跨年代的差异里,有一部分来自传感器,不来自海洋。做长期趋势时,这一部分无法从数据内部估计出来,只能靠外部证据(比如与浮标、与其它产品的交叉比对)来约束。

§4.7 冰缘:代理值不是观测

ice 是 7 天中值的海冰密集度。它在产品里有双重身份:既是独立的一张图,又是冰缘带生成代理海温的原料。

机制在官方页写得很清楚:在观测稀缺的冰缘带,用海冰密集度换算出一个代理海温,让插值能把开阔海域的温度一路推到季节性冰缘。换句话说,冰缘带里那些看起来连续的 sst,是从冰情推出来的,不是测出来的。

这带来一个使用边界:在冰缘附近做「海温趋势」,很可能测的是冰情的趋势。北极边缘与南大洋的冰缘位置年际变化大,同一个格点今年是开阔水、明年是浮冰,sst 序列就会出现跳变——那一段不是海温变了,是格点换了性质。

判别办法是同时把 ice 读出来,看目标格点在时间上是否长期为零。任何 ice 大于零的日期,其 sst 都应被标注为「含代理成分」。

§5 工具层:怎么取、怎么读、怎么验

§5.1 四条获取路径

路径 形态 适合 注意
NCEI 直连目录 按年月分目录的 .nc 文件,HTTP 列目录 要原始文件、要可引用路径 无注册、无令牌;单连接速度一般
THREDDS 目录服务,可按变量与时间切片 要按需取子集 官方 CDR 页列出的入口
ERDDAP 表格式查询与子集 要少量点位的时序 同样是官方页列出的入口
AWS / GCS 镜像 同一批 .nc,另有逐日 Zarr 云上训练、要随机读 Zarr 只在 AWS 那份里有

四条路给的字节应当一致,但目录结构不一致:直连是 access/avhrr/YYYYMM/,S3 是 data/v2.1/avhrr/YYYYMM/,GCS 与 S3 同构但没有 avhrr-zarr。写死路径的脚本换一条路就要改。

§5.2 先算体积,再决定怎么下

单文件 1.5 MB 看起来很小,乘上四十五年的天数就是 27 GB;再乘四变量解包成 float32,落盘会膨胀到上百 GB。先量一遍再动手。

#-- 只读目录索引,不下载数据;返回该月文件数与字节数
import re
import urllib.request

base = "https://www.ncei.noaa.gov/data/sea-surface-temperature-optimum-interpolation/v2.1/access/avhrr/"
html = urllib.request.urlopen(base + "202610/", timeout=60).read().decode("utf-8", "ignore")
sizes = [int(x) for x in re.findall(r'<td align="right">(\d{7,})</td>', html)]
print(len(sizes), sum(sizes), round(sum(sizes) / 1024 ** 2, 1), "MiB")
#-- 期望:文件数等于当月天数(含未定版),体积在 38–40 MiB 之间

这段脚本的正则只抓七位以上的纯数字单元格,日期列带连字符不会被误抓。把它套在 542 个目录上循环,得到的就是 §2.1 那张表。

§5.3 读一个文件

xarray 会自动应用 scale_factor 与 _FillValue,读出来直接是摄氏度、缺测为 NaN。

#-- 依赖:xarray、netCDF4(或 h5netcdf)
import xarray as xr

ds = xr.open_dataset("oisst-avhrr-v02r01.20261013.nc")
print(dict(ds.sizes))
print(ds.sst.attrs["scale_factor"], ds.sst.attrs["_FillValue"])
sst = ds.sst.isel(time=0, zlev=0)
print(float(sst.sel(lat=22.625, lon=157.625, method="nearest")))
print(float(ds.anom.isel(time=0, zlev=0).sel(lat=22.625, lon=157.625, method="nearest")))
#-- 期望:sizes 为 {'time': 1, 'zlev': 1, 'lat': 720, 'lon': 1440}
#-- 期望:scale_factor 为 0.01,_FillValue 为 -999
#-- 期望:两个数都在 -3 到 45 与 -12 到 12 之间,且量级相近

如果不想让 xarray 代劳,用 h5py 直接读会拿到 int16 原始值,需要自己乘 0.01、自己把 -999 换成 NaN。两种做法都对,混用会出错:xarray 读出来的已经是浮点,再乘一次 0.01 就变成百分之一度。

§5.4 拼成时间立方体

一年的数据是 365 个文件,直接 open_mfdataset 会把 365 个文件的坐标对齐、按 time 拼成一维,得到 (time, lat, lon) 的三维立方。

#-- 按月分块拼接,避免一次性打开上千个文件句柄
import glob
import xarray as xr

files = sorted(glob.glob("oisst-avhrr-v02r01.2025*.nc"))
ds = xr.open_mfdataset(files, combine="by_coords", chunks={"time": 30})
print(ds.sst.shape, ds.time.values[0], ds.time.values[-1])
#-- 期望:形状为 (365 或 366, 720, 1440)
#-- 期望:首尾时间相差一年减一天

按年拼、按需 chunks,是唯一可行的策略。想一次性把整个序列的 sst 全读进内存,需要「天数 × 1,036,800 × 4 字节」,约 68 TB。

§5.5 四项校验

拉回来之后先别急着建模,跑一遍这个。

#-- 形状、维度、值域、填充比例,四项一次性过
import numpy as np
import xarray as xr

ds = xr.open_dataset("oisst-avhrr-v02r01.20261013.nc")
sst = ds.sst.isel(time=0, zlev=0)

assert sst.shape == (720, 1440), sst.shape
assert ds.sizes["time"] == 1 and ds.sizes["zlev"] == 1
assert float(sst.min()) >= -3.0 and float(sst.max()) <= 45.0
assert abs(float(ds.lat[0]) + 89.875) < 1e-6
print("缺测比例", round(float(np.isnan(sst).mean()), 3))
#-- 期望:缺测比例在 0.3 到 0.4 之间,主要来自陆地

四项里最有价值的是第二项和最后一项。维度那一项能立刻抓出「把 zlev 当变量名」的低级错误;缺测比例那一项是健康指标——它常年稳定在三成上下(陆地约占地球表面三成,另有一小部分海洋格点当日无有效分析),某天若明显偏离,多半是掩膜或打包出了问题,而不是海平面上升了。

§5.6 一个不报错的错:S3 上同一天有两份

前面提过,云端镜像里的未定版不会立刻删。检查办法只有一条:按日期去重,而不是按对象数。

#-- 列出某个前缀下的对象,数一数有没有重复日期
curl -s "https://noaa-cdr-sea-surface-temp-optimum-interpolation-pds.s3.amazonaws.com/?list-type=2&prefix=data/v2.1/avhrr/202610/&max-keys=1000" \
  | grep -o 'oisst-avhrr-v02r01\.[0-9]\{8\}' \
  | sort | uniq -c | sort -rn | head
#-- 期望:最近十几天的计数为 2(终版与未定版并存),更早的为 1

这个错不会抛异常。它只会让「平均海温」被某些日子重复计入,让时间序列的采样间隔变得不均匀。所有按对象前缀枚举的流程,都该在下载前做一次这样的去重。

§5.7 云端 Zarr:为随机读准备的那一份

AWS 镜像里有一棵 data/v2.1/avhrr-zarr/YYYY/MM/oisst-avhrr-v02r01.YYYYMMDD.zarr/ 的树。每个日文件对应一个独立的 Zarr 存储,带 .zmetadata 汇总与按变量的分块目录,单块十几到三十几 KB。

它的价值在于按块读。想取某个小区域、某几天的 sst,走 Zarr 只需要读几个块,不必把整个 1.5 MB 文件拉下来再切片。对训练时的随机采样,这个差别是数量级的。

代价是它多一层工具依赖(zarr / xarray 的 zarr 后端),且只有 AWS 那份有。做可复现实验时,把「用的哪条路径、哪个前缀」写进记录,比写「用的是 OISST」有用得多。

§5.8 §4.2 的案例在这一层的落地

回到那支养殖预警团队。他们最后定下的取数纪律是五条:

  1. 只取目标格点与周围八邻域,用 ERDDAP 或 Zarr 按块取,不下全量;
  2. 每次取数先跑 §5.5 的四项校验,缺测比例异常的那天单独标记;
  3. 时间轴按年拼、按块读,绝不把日文件当独立样本随机打乱;
  4. 下载前按日期去重,避免未定版与终版重复计入;
  5. 把 err 与 ice 一起取回来,作为筛选与标注的依据,而不是只用 sst。

五条里有三条是为了对付「不报错的错」。这也是这份数据在工程上最需要纪律的地方:它太容易拿到,以至于没人愿意在拿到之后再多做一步检查。

§5.9 批量下载:清单、并发与续传

把四十五年一次拉完是件很平常的事,27 GB 在今天的带宽下也就是几小时。真正会出问题的不是速度,是「拉回来一半、不知道缺了哪一半」。

第一步该做的不是下载,是生成清单。日期不能用「从 1981 数到 2026」手写,闰年、月末天数、以及 1981 年 9 月只有三十天这些事实,交给日历库比自己算可靠。

#-- 按真实日历逐日生成 URL 清单,跨年不跳月
import datetime as dt

d, end, urls = dt.date(1981, 9, 1), dt.date(2026, 10, 27), []
while d <= end:
    urls.append(f"{d:%Y%m}/oisst-avhrr-v02r01.{d:%Y%m%d}.nc")
    d += dt.timedelta(days=1)
open("urls.txt", "w").write("\n".join(urls))
print(len(urls))
#-- 期望:16493,与目录索引清点的文件数一致;不一致就说明日历或终点写错了

第二步是并发与续传。

#-- 限四路并发、断点续传、单文件失败重试两次
base="https://www.ncei.noaa.gov/data/sea-surface-temperature-optimum-interpolation/v2.1/access/avhrr"
xargs -P 4 -I{} curl -sS --retry 2 -C - --create-dirs -o "data/{}" "$base/{}" < urls.txt

三处细节值得解释。并发开到四而不是十六,是因为这条链路对单连接有节流,并发太高反而整体变慢,且更容易被中途断开;-C - 让中断后重跑只补差额,不必从头再来;重试写在 curl 里而不是套一层循环,避免一次失败导致整批重排。

第三步是回来对数:find data -name "*.nc" | wc -l 的结果必须等于清单行数。少了就是少了,不要用「应该差不多」放过——少的那几天,往往集中在同一段网络抖动的时刻,正好形成一段时间上的窟窿,而窟窿在聚合统计里不会报错,只会让曲线悄悄变平。

§6 层与层之间:它在本库中的位置

§6.1 库内的海洋与气候家底

这套库以医学数据为主,地球观测是近几年才补进来的一块。能与 OISST 形成上下游关系的,目前有三类:再分析场(ERA5 单层)、陆地站点观测(GHCNd)、卫星影像分类基准(EuroSAT)。三者与 OISST 的关系都不是替代,而是「同一套坐标,不同的物理量」。

§6.2 与 ERA5 的分工:同格距,不同出身

两者都是 0.25°,都把全球切成 720×1440,都能给出逐日的海表温度。差别在出身。

ERA5 的海温是海洋模式同化的产物:它继承了模式的时间平滑与物理自洽,也继承了模式对极值的压缩。OISST 的海温是卫星反演加现场订正再插值:它更贴观测,也更容易在观测稀疏处失真。

实践中的分工很清楚:要一个自洽的多要素背景场(风、气压、辐射、海温一起用)→ ERA5;要一个尽量贴观测的海温判定(热浪、白化、阈值)→ OISST。 两者同时用也常见:ERA5 给大气强迫,OISST 给海洋响应。

§6.3 与 GHCNd 的分工:海与陆

GHCNd 是陆地站点的逐日气温与降水,点是点,天是天。OISST 是海洋的格点场。

两者在同一项研究里经常配对出现:陆地上的热浪用 GHCNd 判,海面上的热浪用 OISST 判,再比较两者的同步性。这时要注意两边的「日」定义不同——GHCNd 的日值来自当地观测时段的统计,OISST 的日值是 UTC 正午的一个分析时刻。跨日界线比较时,会差一天。

§6.4 与 EuroSAT 的分工:同一片海,两种看法

EuroSAT 是 Sentinel-2 的 64×64 瓦片,任务是地表覆盖分类;OISST 是海温场。二者在「海岸带」这个场景里会相遇:用 EuroSAT 判海岸带的地物类型(养殖区、滩涂、红树林),用 OISST 给同一片海配温度背景。

分辨率差得很远——10 米对 20 多公里,差了三个数量级。这种配合只能做「区域背景」层面,不能做「逐像素修正」。

§6.5 与 AQS 的分工:一个已在前文用过的类比

AQS 是地面空气质量站点,与 OISST 没有物理关系,但在方法上同构:都是「观测稀疏、需要空间代表性判断、需要区分真值与插值」。

把 AQS 的站点与 OISST 的格点放在一起看,会发现同一类问题在两套数据里长得一样:站点/格点与目标位置的空间错配、时间聚合口径的错配、以及「数据有值不等于数据可信」。这类问题不随领域变化,只随尺度变化。

§6.6 检索路径建议

按需求找:要海温本身 → 本篇;要大气多要素 → ERA5;要陆地气温 → GHCNd;要卫星影像 → EuroSAT;要地面空气 → AQS。要做「海洋热浪 + 沿岸人群健康」的组合研究,从本篇出发到公共卫生类条目,中间那层「格点聚合到行政单元」需要自己写,且聚合权重(面积还是人口)会显著改变结论。

§7 质量评估与局限:它不该按什么标准评价

§7.0 阅读本节前需要知道的一件事

用「观测数据集」的尺子量它,会得出「全是插值、处处有值、不可信」的结论;用「机器学习基准」的尺子量它,会得出「没有标签、没有划分、没有排行榜」的结论。两种结论都对,但都没回答它为什么被引用了四十年。

它被引用的原因在于连续与一致:同一个网格、同一条处理链、同一套变量定义,贯穿四十五年。观测数据做不到这一点——卫星换了六代,浮标网从几十个长到几千个,南大洋几十年没有船去过。对于任何想把「历史海温」当作输入或标签的模型,连续比单点精度重要得多。

所以评价它该用的尺子是:作为一条跨越四十五年的分析链,它的同质性、可追溯性与边界标注做得怎么样。

§7.1 三种常见的评价框架错位

常见错位 表现 应该怎么想
拿浮标的精度标准套它 抱怨某格点与浮标差 1.5 °C 格点与点本来就有代表性差异,该比的是偏差的统计结构与季节依赖
拿原始观测的标准套它 抱怨「到处都有值,肯定是编的」 插值填洞是产品定义的一部分,不填洞就不叫 analysis
拿排行榜数据集的标准套它 抱怨没有训练测试划分、没有指标 它是原料,不是考题;划分与指标由任务定义

§7.2 DAIMS 二十四项逐条对照

DAIMS 原本面向社会科学调查数据,这里借用它的检查点,把这份格点产品的成熟度摊开。

# 检查项 状态 说明
1 宽格式 ⚠️ 网格数据不是表格;要宽表化须先按点位或区域抽取
2 唯一标识 ✅ 文件名日期即主键,全球唯一且定长
3 特殊字符 ✅ 文件名全为 ASCII,无空格
4 重复行 ✅ 一天一文件,无重复日期;云端未定版需按日期去重
5 缺失编码 ✅ -999 统一填充,_FillValue 显式声明
6 标签标识 ✅ 四个变量名固定,CF 与 ACDD 双重约定
7 罕见类分组 ✅ 无类别概念;冰区与陆地的区分由 ice 与掩膜承担
8 偏倚评估 ⚠️ 观测系统的时变偏倚有文献讨论,产品内无量化字段
9 数据字典 ✅ 变量属性齐全,另有 C-算法文档 与 CDR 变量表
10 信息性缺失解释 ⚠️ -999 不区分陆地、冰下、质控剔除三种成因
11 设备记录 ✅ platform、instrument、source 三属性列明来源
12 共线性 ⚠️ sst 与 anom 高度相关,同作特征等于重复计权
13 编码映射 ✅ 冰密集度到代理海温的转换在文档中有说明
14 时间戳处理 ✅ 单一 UTC 日,time 与文件名一致
15 划分建议 ❌ 无任何训练/验证划分建议,逐日样本非独立
16 泄漏讨论 ❌ 官方未讨论逐日递归带来的样本相关问题
17 标签分布 ✅ 无标签概念;值域由 valid_min/max 显式约束
18 测量偏倚 ⚠️ 近岸格点含陆地、冰缘为代理值,两类偏倚无逐格标注
19 外部验证建议 ⚠️ 文献中有大量交叉验证,产品页未给统一协议
20 版本记录 ✅ DOI、DSI 编号、C01606 与文件内版本属性齐备
21 预处理脚本 ⚠️ 源码包公开,但只覆盖前向生产,不含回溯重算
22 合规要求 ✅ 使用协议原文明确,ISO 约束字段完整
23 多模态对齐 ⚠️ 与微波组合产品的时间窗只覆盖 2002–2011
24 去标识化 ✅ 无个人数据;船舶观测在上游已聚合到网格

DAIMS 评分:18 / 24。按满项 1 分、半分项 0.5 分、零分 0 分计,十四个满项、八个半分项、两个零分项。

评分解读:分数落在中上段,与「文档扎实、口径清晰,但对现代机器学习的使用习惯毫无预设」的定位吻合。满项集中在标识、编码、版本、合规这些「一旦做好就不用动」的维度;零分集中在划分与泄漏这两项「需要为下游重新设计」的维度——它们不是疏漏,而是这份数据诞生时还没有人这样用它。

对你意味着什么:不要指望官方告诉你该怎么切分训练集。逐日递归这件事,官方在算法文档里说了机制,但没有说它对建模意味着什么。那一层判断只能自己做。

§7.3 逐条局限

局限 具体表现 后果
逐日递归 当天分析以上一天为初猜 日样本不独立,随机划分高估精度
硬截断 sst 被钳在 -3 至 45 °C 极值统计低估尾部
近岸混像元 0.25° 格内含陆地 沿岸与海湾偏差大且季节相关
冰缘代理 冰缘 sst 由冰密集度反推 冰缘趋势可能测的是冰情
断点不回溯 2016、2021、2023 三处前向改动 跨断点长序列非同质
传感器假设 假设全部 AVHRR 同信噪比 跨年代差异含仪器成分
距平基准旧 1971–2000 与 1991–2020 体系不可直接比
云端重复 未定版与终版短时并存 按对象枚举会重复计日

§7.4 该被追问什么、不该被追问什么

用「为什么没有逐格的不确定度分解」去问责它是合理的,因为 err 确实是合成的标量。但用「为什么没有原始卫星像元」去问责它不合理——它的定义就是分析场,原始像元在 L1/L2 产品里。

真正该追问的有三件。

第一,2016 年那次改版的影响能否被分离。官方给了四类改动(现场观测来源、Argo、卫星输入、冰转换),但没有给逐项归因的试验。想把「海温变化」与「算法变化」分开,只能靠外部证据。

第二,近岸的可用性边界在哪。产品没有任何字段标注「这一格离岸多远、含多少陆地」。使用者只能自己用地表掩膜算,而不同的掩膜会给出不同的边界。这是一个真实存在的空白。§4.2 的案例撞上的正是这堵墙:他们要的那片海,在两套掩膜下分别落在「可用」与「不可用」两侧,结论因此翻转。

第三,未定版与终版的差异有多大。官方说终版以未定版为初猜、补三天数据重算,但没有公布两者的统计差异。做近实时应用的人,实际上是在一个未量化的误差上做决策。

三件事共同说明一件事:这份数据的「连续性」是靠一条不断打补丁的链换来的,不是靠一次设计到位的规范。 用对了,它是一把长尺;用错了,它会把三次换零件读成三次气候变化。

§7.5 外部验证:怎么用别的数据检验它

参照 能验证什么 注意
现场浮标 单点偏差与季节依赖 点位极少且集中在北半球航线附近
微波海温 开阔洋面的独立性检验 微波在近岸失效,与 OISST 的强项互补
Argo 剖面 次表层到表层的代表性的 剖面深度不等,需先插到表层
其它再分析海温 大尺度结构的一致性 同化体系不同,极值处差异最大

这些组合没有官方协议,因此「提升几个点」「偏差多少」这类说法必须附上时段、区域与匹配方法才成立。

§8 生态与版本:它为什么还能被用下去

§8.1 版本时间线

时间 事件 证据
1981-09-01 序列起点 目录首个日文件
2007 Reynolds 等给出逐日 0.25° 的方法 J. Climate 20:5473
2013-09 CDR 算法文档 Rev.2 定稿 算法基线文档 Rev.2
2016-01-01 v2.1 的算法改进生效(现场观测、Argo、卫星、冰转换) 产品页与 DOI 元数据
2017-11 全序列由 NetCDF-3 转 NetCDF-4 文件 comment 属性
2020-03 v2.1 发布 DOI 元数据页
2020-04-01 v2.1 顶替 v2 产品页
2020-04-26 v2 停止生产 产品页
2021-10-01 v2.1a:卫星输入换 ACSPO 产品页 Update History
2022-12-05 1° 周平均 OI.v2 在 NCEP 侧停止 产品 FAQ
2023-04-01 v2.1b:船测偏差订正改为逐月时变 产品页 Update History

时间线里最值得注意的一格是 2017-11。它意味着「v2.1 覆盖 1981 年至今」这句话,在字节层面是 2017 年之后才成立的——在此之前,早年的文件是另一种容器。做字节级校验(比如按 md5 比对历史版本)的人,会在这里撞上整批不一致。

§8.2 它在生态中的位置

OISST 处在一个很特殊的位置:它既是研究的原料,又是业务的基础设施。

在业务侧,海洋热浪监测、珊瑚白化预警、渔业管理、海洋牧场保险的触发条件,很多都以它为判定依据。在科研侧,它是最常被拿来当「参照场」的那一个——新出的海温产品几乎都要与它比一遍。这种双重身份带来一个副作用:当它自己出错时,错误会同时出现在判定和验证两端。

§8.3 谁在依赖它

  • 业务层:海洋热浪与白化监测的阈值判定,多数以逐日距平为基础
  • 科研层:海温产品互比、模式评估、海气通量估算的标准参照
  • 工程层:区域海洋模式的边界条件、卫星产品的融合背景场
  • 教学层:海洋数据处理的入门样例——文件小、变量少、格式标准

§8.4 它为什么能持续

一套 1981 年起步、分辨率只有二十几公里、每天只有一个时刻的产品,为什么没被高分辨率产品取代?答案有三层。

第一层是长度不可复制。四十五年、逐日、无缺日的海温序列,全世界只有个位数。任何新产品想积累到同样的长度,只能等。

第二层是口径稳定。变量名、单位、网格、填充值四十年没变过(容器变过一次,语义没变)。这意味着二十年前写的读取脚本今天还能跑。对基础设施而言,这是最高的美德。

第三层是维护是活的。它不是一份冻结的存档:v2.1a、v2.1b 说明这条链还在被修,产品页的更新历史还在增长。冻结的数据会过时,活着的链会持续输出。

三层叠加的结果是:没有人把它当最终答案,但也没有人能绕开它做时间序列。

§8.5 引用与许可

许可这件事,官方给了三份互不一致的材料。

CDR 使用协议 PDF 是最接近许可声明的一份,原文写「the CDR data sets are non-proprietary, publicly available, and no restrictions are placed upon their use」。同一份文件还写明:生产软件可能不属于政府所有,不在开放数据政策范围内。

ISO 19115 元数据里,accessConstraints 与 useConstraints 两条都是 otherRestrictions,otherConstraints 写的是「Cite as: …」。这是机器可读层面唯一能查到的约束,含义是「另有限制,须按指定方式引用」。

数据文件本身没有任何 license 属性。CF-1.6 与 ACDD-1.3 的约定里没有这一项,所以文件层面查不到。

三份材料合起来,能写出的最准确表述是:公有领域性质,无使用限制,但要求按指定格式引用;官方未给 SPDX 标识。 写成 CC0 或 CC BY 都是替官方做主,写成「保留所有权利」则是反向的错。

还有一处细节值得记下:那份使用协议 PDF 至今仍写着 NCDC(2015 年已并入 NCEI)、仍引用 v2 的 DOI 10.7289/V5SQ8XB5、仍把 Reynolds 列为数据作者。它是 v2 时代的文本,没有随 v2.1 更新。真正该引的是 10.25921/RE9P-PT57。

§9 使用指引:三条路径,一份最小实现

§9.1 三种角色,三条路

你的角色 建议路径 关键动作
想快速验证一个时序模型 取一个海区、十年的日文件,按年拼 先跑通形状与缺测校验,再谈模型
要做海洋热浪或异常判定 用 sst 自建气候态,或用 anom 但统一基准 阈值法之前先定基准期,见 §4.4
要做全球尺度的预训练 走 Zarr,按块随机采样 按块而非按日切分,避免相邻日泄漏

§9.2 在 AI 流水线中的位置

卫星 L2/L3 海温 + 浮标 + 船舶 + Argo
        ↓ 偏差订正、最优插值、冰缘代理
OISST 日文件(0.25°,一天一张)      ← 训练目标、验证参照、业务阈值
        ↓ 聚合到区域 / 时间窗
热浪指数、白化风险、渔场环境特征、模式边界条件

这条链说明一个常见误用:把 OISST 当「真值」去训练一个超分辨率模型,然后用同一份 OISST 的高分辨率版本验证。两边同源,验证的是插值一致性,不是分辨率提升。

§9.3 一份最小可跑的实现

下面这段不依赖 xarray,只用 h5py 与 numpy,把「读文件—去填充—打包成样本」这条链完全摊开。

#-- 依赖:h5py、numpy、torch;输入为若干日文件路径
import h5py
import numpy as np
import torch
from torch.utils.data import Dataset

class OISSTWindows(Dataset):
    def __init__(self, paths, win=7, size=32):
        self.paths, self.win, self.size = paths, win, size

    def __len__(self):
        return len(self.paths) - self.win

    def _read(self, path):
        with h5py.File(path, "r") as f:
            raw = f["sst"][0, 0].astype("float32")
        sst = raw * 0.01
        sst[raw == -999] = np.nan
        return sst

    def __getitem__(self, i):
        cube = np.stack([self._read(p) for p in self.paths[i:i + self.win]])
        y, x = 300, 800
        patch = cube[:, y:y + self.size, x:x + self.size]
        patch = np.nan_to_num(patch, nan=0.0)
        return torch.from_numpy(patch), torch.from_numpy(patch[-1])

ds = OISSTWindows(sorted(__import__("glob").glob("oisst-avhrr-v02r01.2025*.nc")))
x, y = ds[0]
print(x.shape, y.shape, float(y.mean()))
#-- 期望:x 为 (7, 32, 32),y 为 (32, 32)
#-- 期望:均值在 10 到 30 之间,取决于取的是哪片海

注意 paths 必须按时间排序。这个 Dataset 的样本是「连续七天的一小片海」,打乱文件顺序会得到七段互不相邻的日期拼成的立方体,训练仍能收敛,但学到的不是时序。

§9.4 评估时最少要报的三件事

要报的 为什么 怎么报
时间划分方式 逐日递归使样本相关,随机划分高估精度 写明「按年」「按块」还是「随机」,并给切点
距平基准期 1971–2000 与 1991–2020 不可直接比 写清用的是文件自带 anom 还是自建气候态
是否剔除高误差格 err 大的格点插值占主导 给出阈值与剔除比例

§9.5 三种流水线的形态,与它们各自的错法

同一份数据,三种任务,三种切法。切错了,模型照样收敛,指标照样好看。

任务 数据形态 常见错法 该怎么做
单点海温时序预测 取一格、四十五年,成一维序列 随机抽点做训练与验证 按年切,留出完整年份做测试
区域场预测(如热浪识别) 取一片海、若干年,成三维立方 逐帧随机切分 按时间块切,且预测窗口不得落在训练窗口之后
全球预训练与补缺 Zarr 按块采样 按日文件顺序顺序读,块内样本高度相似 打乱块,但同一块内的相邻日不要分散到训练与测试

第二行和第三行的错法有个共同根源:滑动窗口让样本互相重叠。取七天窗口、步长一天,相邻两个样本有六天相同。把它们随机分到两边,等于让模型在测试集里认出了训练集的邻居。这条规律在任何时序数据上都成立,只是 OISST 的逐日递归让它更严重——不仅窗口重叠,连「不重叠的两段」之间也通过初猜相连。

§4.2 的案例在这一层给出的教训是:那支团队最初的验证方式是「随机抽 20% 的日子做测试」,精度高得反常;改成按年切之后,误差翻了一倍多。翻倍之后的数字才是他们能拿去和浮标对的数字。

§10 AI 使用声明

栏目 内容
性质 卫星与现场观测经最优插值得到的分析场,非纯观测
用途 海温时序建模、热浪与异常判定、产品互比、区域模式边界
不建议用途 近岸与养殖区尺度判定、逐小时应用、把日样本当独立样本、跨断点直接比趋势
伦理 无个人数据;下游若涉及渔业保险或灾害赔付,须披露空间代表性误差
引用 DOI 10.25921/RE9P-PT57 + Huang et al. 2020
许可 公有领域性质、无使用限制、须按指定格式引用;无 SPDX
版本 产品名 v2.1 与文件名 v02r01 需同时写出,并注明取数日期
状态 在线,逐日更新,终版延迟约 15 天

§11 常见误读与避坑清单

常见说法 实际情况 证据
「OISST 只有 v2 一个版本」 现役是 v2.1,v2 已于 2020-04-26 停产 产品页 Version 2.1 一节
「final 与 preliminary 是两个目录」 同一目录同一路径,靠文件名后缀区分,终版覆盖未定版 access/ 下只有 avhrr
「未定版会被立刻删除」 直连目录里被覆盖,AWS 镜像里两份并存数日 S3 前缀下同日期两个对象
「许可是 CC0」 使用协议写 no restrictions,但无 SPDX,ISO 标 otherRestrictions Use Agreement PDF 与 ISO 字段
「距平是对 1991–2020 算的」 基准期是 1971–2000 文件 references 属性
「sst 单位是 degC」 属性写作 Celsius,按 degC 匹配会失败 变量 units 属性
「纬度从 -90 开始」 格心从 -89.875 开始,-90 是格边 坐标变量与全局属性不同源
「四个变量是四种观测」 anom 是 sst 减气候态,err 是自评误差,ice 是冰情 变量 long_name
「每天的场是独立算的」 当天分析以上一天的分析为初猜 C-算法文档 §1.2 与 §3.4
「0.25° 在全球一样大」 赤道约 27.8 公里,60°N 约 13.9 公里 经纬网格几何
「v2.1 是全序列统一重算的」 三处改动只前向生效,历史未重算 产品页 Update History
「单文件 1.7 MB,×16,500 就是总量」 实际 27.43 GB,线性外推高估约 3% 逐月索引求和
「有值就代表测到了」 冰缘带 sst 由冰密集度反推 产品页与 C-算法文档 §3.3

附录 A 速查卡

键 值
产品名 OISST v2.1(AVHRR-only,0.25° 逐日)
文件命名 oisst-avhrr-v02r01.YYYYMMDD[_preliminary].nc
直连目录 …/v2.1/access/avhrr/YYYYMM/
S3 前缀 data/v2.1/avhrr/YYYYMM/、data/v2.1/avhrr-zarr/YYYY/MM/
DOI 10.25921/RE9P-PT57
元数据号 gov.noaa.ncdc:C01606、NCEI DSI 3650_02
变量 sst、anom、err、ice
打包 int16,scale_factor 0.01,填充 -999
网格 720×1440,格心 -89.875–89.875 / 0.125–359.875
时间 逐日,UTC 正午,纪元 1978-01-01 12:00
延迟 未定版 1 天,终版约 15 天
许可 公有领域性质,须引用,无 SPDX

附录 B 变量与属性表

属性 sst anom err ice
long_name Daily sea surface temperature Daily sea surface temperature anomalies Estimated error standard deviation of analysed_sst Sea ice concentration
units Celsius Celsius Celsius %
valid_min -300 -1200 0 0
valid_max 4500 1200 1000 100
scale_factor 0.01 0.01 0.01 0.01
_FillValue -999 -999 -999 -999

附录 C 术语表

术语 含义
OI 最优插值,按误差协方差给观测加权并填补空缺的统计方法
AVHRR 甚高分辨率辐射计,红外通道反演海温,1981 年起的核心输入
DOISST 逐日最优插值海温的另一种缩写,与 OISST 同指
超级观测 落在同一网格内的多个像元先平均成一个观测,再进 OI
EOT 经验正交函数,用于把卫星与现场观测的偏差分解到空间模态上
距平 当日海温减气候态,本文基准期为 1971–2000
气候态 多年平均的参考场,决定距平的零点
冰缘带 海冰边缘的开阔水域,观测稀缺,用代理海温填充
代理海温 由海冰密集度换算出的海温,不是直接测量
CDR 气候数据记录,NOAA 对长序列、可持续产品的正式认定
C-算法文档 气候算法理论基线文档,描述算法原理与参数
掩膜 标出哪些格点有效、哪些是陆地或无结果的布尔场
格心 / 格边 网格单元的中心点与边界,二者差半格

附录 D 常见问题

Q1:这份数据要注册才能下吗?
不用。直连目录、S3 与 GCS 都允许匿名列举与下载,没有令牌、没有点击同意的环节。CDR 页有一个可选的用户登记表,用于接收产品更新通知,不登记不影响取数。

Q2:为什么最早的文件比最新的文件还大?
压缩率不同。早期分析场里有效海域相对少、陆地掩膜占比高,压缩后的体积反而偏大;后期观测更密、场更平滑,压缩率更高。极差约 18%,做容量规划用中位数。

Q3:能不能只用 anom,不用 sst?
可以,但要写清基准期。anom 是相对 1971–2000 的距平,如果你的阈值来自另一套基准的产品,两者不可直接比。跨产品比较时,最稳的做法是各自取 sst、自建同一段气候态。

Q4:为什么有些格点的 sst 是 -3 度?
可能是真的接近冰点,也可能是被 valid_min 钳住了。区分办法是看同一格的 ice:冰密集度大于零时,sst 通常由冰情反推,接近冰点是正常的。

Q5:S3 上的 Zarr 和 .nc 是两份数据吗?
同一份数据的两种组织方式。Zarr 按块切分,适合随机读;.nc 是一天一个完整文件,适合顺序读与归档。两者内容应当一致,但 Zarr 只在 AWS 那份镜像里有。

Q6:为什么我的时间轴从 1978 年开始?
因为 time 的单位是 days since 1978-01-01 12:00:00。1978 是网格模板的纪元常数,不是数据起点。数据起点是 1981-09-01。

Q7:能拿它算全球平均海温吗?
能,但必须乘纬度余弦做面积加权。1,036,800 个格点在高纬代表的面积远小于赤道,直接求平均会系统性高估高纬权重。

Q8:这算不算「AI-ready」?
按本文的口径算:格式标准、变量显式、许可清晰、可匿名获取、有云端 Zarr 版本。它缺的是划分与泄漏提示,那两项要使用者自己补。

编辑说明

核验时间 2026-10-29。方法:逐层列举 NCEI 直连目录(顶层 542 个月目录的索引、以及 542 个月目录内的文件清单),按 Size 列求和得到总体积与单文件中位、极值,并用日期区间天数交叉验证文件数;下载 2026-10-13 终版与 2026-10-27 未定版两个文件,用 h5py 读取全部全局属性、变量属性、形状与压缩设置,取得打包系数、属性域、填充值、坐标步长与 title 截断长度;读取产品页、CDR 页、DOI 解析后的元数据页与 ISO 19115 XML,取版本沿革、子版本时间、气候态基准、约束字段与引用格式;读取 CDR 使用协议 PDF、C-算法文档(Rev.2, 2013)与成熟度矩阵 PDF,取许可原文、OI 参数、传感器假设与文档版本;列举 S3 与 GCS 的公开 bucket 前缀,确认镜像结构、Zarr 的存在范围与未定版并存现象。未做任何分布统计,因此全文没有海温均值、极值频率或区域偏差数字;未下载全量 27 GB,总体积来自目录索引求和而非下载计量;THREDDS 与 ERDDAP 两条通道在本环境未逐一验证内容,正文只按官方 CDR 页的入口标注陈述,未延伸描述其目录结构。文中「赤道 27.8 公里」等尺度数字为按 0.25° 与地球半径换算,非官方表述。成熟度矩阵 PDF 为单页空白模板(页眉标注 2013-07-11),未含本产品的评级,故正文未引用其结论。


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • era5-single-levels — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康 / 疾病监测
  • ibtracs — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康 / 疾病监测
  • argo-gdac-floats — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康 / 疾病监测
  • our-world-in-data — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康
  • ndbc-buoy — 共享标签:公共卫生与流行病学 / 时序数据 / 疾病监测
  • noaa-cors-gnss — 共享标签:公共卫生与流行病学 / 时序数据 / 疾病监测
  • amrnet — 共享标签:公共卫生与流行病学 / 全球健康 / 疾病监测
  • wpp — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康
  • ghcn-daily — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康
  • usgs-comcat — 共享标签:公共卫生与流行病学 / 时序数据 / 全球健康

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集