3. 近岸SST气候态基准的构建与验证

为什么近岸气候态不能直接取多年平均

近岸SST长期存在增暖趋势,若直接把1991—2020年全部日值做算术平均,得到的基准会偏向“中间年份”,导致早期年份系统性偏低、近期年份系统性偏高,距平场出现虚假的正负偏移。本例采用去趋势逐日气候态:先对每个日历日(或候)的多年序列拟合线性趋势并扣除,再求平均,最后把趋势项加回到基准中心年份,得到一条既保留季节循环、又不被长期变化污染的基准曲线。

核心计算分三步:①按日历日(DOY)分组,对每个DOY的N年序列做最小二乘线性拟合 SST = a·t + b;②去趋势残差 r = SST − (a·t + b),求残差均值 r̄;③基准值 clim(DOY) = a·t_ref + b + r̄,其中 t_ref 取基准中心年份(如2005.5)。这样基准代表“中心年份的典型季节循环”。

验证用独立年份:留出若干年(如2016—2020)不参与构建,计算这些年份相对基准的距平,检查距平年际均值是否接近0、是否存在随时间的漂移。若留出年份距平均值绝对值超过0.15 ℃或呈单调漂移,说明趋势处理或窗口长度不合适。

去趋势逐日气候态构建与独立年份验证 多年逐日SST 1991–2020 质量标记后数据 按DOY分组 每个日历日 N=30年序列 线性趋势拟合 SST = a·t + b 最小二乘 去趋势残差 r = SST − (a·t+b) 求残差均值 r̄ 合成基准场 clim(DOY)=a·t_ref+b+r̄ t_ref = 2005.5 独立年份验证 留出2016–2020 计算距平年际均值 稳定性判据 |均值| ≤ 0.15 ℃ 无单调漂移 输出基准场 逐日/逐候 clim 供距平计算使用

关键实现:逐日去趋势基准的Python实现

下面代码以xarray读取一份示例SST数据集(变量名sst,维度time, lat, lon),完成逐日去趋势基准构建,并用留出年份验证。示例数据为教学构造,实际使用时替换为你的再分析或观测数据即可。

import numpy as np
import xarray as xr

# 1. 读取并预处理(示例:ds 含 sst(time, lat, lon))
ds = xr.open_dataset("nearshore_sst.nc")
sst = ds["sst"].where(ds["sst"] < 50)  # 简单越界剔除,正式流程用质量掩膜

# 2. 划分构建期与验证期
build = sst.sel(time=slice("1991-01-01", "2015-12-31"))
valid = sst.sel(time=slice("2016-01-01", "2020-12-31"))

# 3. 逐日去趋势基准
def detrended_daily_clim(da, t_ref):
    doy = da.time.dt.dayofyear
    t = da.time.dt.year + (da.time.dt.dayofyear - 1) / 365.25
    out = []
    for d in range(1, 367):
        sub = da.where(doy == d, drop=True)
        if sub.sizes["time"] < 10:
            continue
        y = sub.values.reshape(sub.sizes["time"], -1)
        tt = t.where(doy == d, drop=True).values
        ok = ~np.isnan(y).all(axis=1)
        if ok.sum() < 10:
            continue
        A = np.vstack([tt[ok], np.ones(ok.sum())]).T
        coef, *_ = np.linalg.lstsq(A, y[ok], rcond=None)
        a, b = coef[0], coef[1]
        resid = y[ok] - (a[:, None] * tt[ok][:, None] + b[None, :])
        rbar = np.nanmean(resid, axis=0)
        clim = a * t_ref + b + rbar
        out.append((d, clim))
    return out

clim_list = detrended_daily_clim(build, t_ref=2005.5)

# 4. 独立年份验证:计算留出年份距平年际均值
anom_means = []
for yr in range(2016, 2021):
    sub = valid.sel(time=str(yr))
    doy = sub.time.dt.dayofyear.values
    clim_map = {d: c for d, c in clim_list}
    base = np.stack([clim_map[d] for d in doy])
    anom = sub.values - base
    anom_means.append(np.nanmean(anom))
print("留出年份距平均值(℃):", np.round(anom_means, 3))

运行后观察anom_means:若各年绝对值均不超过0.15 ℃且无逐年单调上升/下降,说明基准稳定;若出现明显漂移,可尝试缩短构建期(如2001—2015)或改用滑动窗口(如15年窗口逐年滚动)重新构建。

候气候态(5天平均)可减少逐日噪声,适合近岸高频波动场景;构建时先按候聚合再拟合趋势,验证判据不变。
去趋势基准代表中心年份的典型状态,不能直接用于跨年代绝对比较;若需比较不同年代,应分别构建各自基准或明确说明基准中心年份。

基准稳定性检查清单

检查项通过条件不通过时的处理
留出年份距平均值|均值| ≤ 0.15 ℃缩短构建期或改用滑动窗口
距平年际漂移无单调趋势检查趋势拟合是否被异常年份主导
逐日基准连续性相邻DOY差值 < 0.5 ℃对基准做3–5天滑动平滑
有效样本数每个DOY ≥ 10年合并为候或月气候态