3. 风暴增水残差的直接相减计算与量纲核对

为什么“直接相减”仍需要一套核对流程

风暴增水残差最朴素的定义是:残差 = 实测潮位 − 调和预报潮位。但这条公式要真正可用,必须同时满足三个前提:同一时刻(时间对齐)、同一单位与同一基准面(量纲与基准统一)、同一有效性(缺测与异常不参与计算)。否则相减得到的“残差”里会混入时区偏移、厘米/米混用、基准面不一致等非风暴信号,后续峰值识别和气压分离都会失真。

本节以某站 6 个逐时时刻为例,演示从原始观测与预报两条序列到“干净残差序列”的完整核对过程。示例数据均为教学假设值,单位统一为 cm,时间统一为北京时间整点,基准面统一为当地理论最低潮面。

示例数据与逐时相减

下表给出 6 个时刻的实测潮位 H_obs、调和预报潮位 H_pre,以及直接相减得到的原始残差 R_raw。其中 04 时实测缺测,05 时实测存在明显跳变(相对前后时刻突变 40 cm 以上),需要标记。

时刻H_obs (cm)H_pre (cm)R_raw = H_obs − H_pre (cm)有效性标记
01:00182165+17有效
02:00205190+15有效
03:00228214+14有效
04:00—236NaN缺测,不计算
05:00298252+46跳变,待核查
06:00262263−1有效

注意 05 时的 +46 cm:它既可能是真实的风暴增水起点,也可能是观测跳变或时间错位。仅凭单点无法判断,必须结合相邻时刻的残差连续性和原始观测曲线形态来核查。

时间对齐、单位统一与缺测标记的实现

下面是一段可直接运行的 Python 示例,完成三件事:把两条序列按整点时间戳对齐(外连接,保留缺测)、统一到 cm、逐时相减并写入有效性标记。示例使用 pandas,数据为上文教学假设值。

import pandas as pd
import numpy as np

# 教学示例数据:时间统一为北京时间整点,单位统一为 cm
obs = pd.Series(
    [182, 205, 228, np.nan, 298, 262],
    index=pd.to_datetime([
        "2023-08-01 01:00", "2023-08-01 02:00", "2023-08-01 03:00",
        "2023-08-01 04:00", "2023-08-01 05:00", "2023-08-01 06:00"]),
    name="H_obs_cm")

pre = pd.Series(
    [165, 190, 214, 236, 252, 263],
    index=pd.to_datetime([
        "2023-08-01 01:00", "2023-08-01 02:00", "2023-08-01 03:00",
        "2023-08-01 04:00", "2023-08-01 05:00", "2023-08-01 06:00"]),
    name="H_pre_cm")

# 1) 时间对齐:外连接,任一侧缺失都保留时间戳
df = pd.concat([obs, pre], axis=1, join="outer").sort_index()

# 2) 单位与基准面核对(此处已统一为 cm / 理论最低潮面,仅做断言式检查)
assert df["H_obs_cm"].dropna().abs().max() < 1000, "疑似单位混用(m 与 cm)"
assert df["H_pre_cm"].dropna().abs().max() < 1000, "疑似单位混用(m 与 cm)"

# 3) 逐时相减,缺测不参与计算
df["R_raw_cm"] = df["H_obs_cm"] - df["H_pre_cm"]

# 4) 有效性标记:缺测 / 跳变 / 有效
df["flag"] = "有效"
df.loc[df["H_obs_cm"].isna() | df["H_pre_cm"].isna(), "flag"] = "缺测"
jump = df["H_obs_cm"].diff().abs() > 40
df.loc[jump.fillna(False), "flag"] = "跳变待核查"

print(df)

运行后 R_raw_cm 列即为原始残差序列,04 时为 NaN,05 时被标记为“跳变待核查”。这一步的关键不是算法复杂,而是把“不可比”的时刻显式排除或标记,而不是让它们悄悄进入残差统计。

残差序列的非风暴信号核查

得到原始残差后,需要回答一个问题:这条残差里是否混入了明显不属于风暴增水的成分?常用核查项包括:

  • 量级核查:正常天文潮预报残差通常在 ±10 cm 量级;若整段残差系统性偏大(如全部 +80 cm),更可能是基准面或单位不一致,而非风暴。
  • 连续性核查:相邻时刻残差突变超过阈值(本例取 40 cm/h)应标记,结合原始观测判断是真实增水还是跳变。
  • 周期性核查:若残差仍呈现明显半日周期(约 12.4 h),说明调和预报基线分潮不足或时间错位,残差中残留天文潮信号。
  • 符号一致性核查:风暴增水一般为正(水位抬升),若残差长期为负且幅度稳定,需怀疑基准面定义相反。
实测潮位与调和预报逐时相减 → 原始残差 → 非风暴信号核查 实测潮位 H_obs 单位:cm 基准面:理论最低潮面 时间:北京时间整点 含缺测与跳变点 调和预报 H_pre 单位:cm 基准面:理论最低潮面 时间:北京时间整点 分潮组合已定 对齐 + 相减 ① 时间戳外连接 ② 单位/基准面断言 ③ R = H_obs − H_pre ④ 缺测 → NaN ⑤ 跳变 → 标记 原始残差 R_raw (cm) 01:00 +17 02:00 +15 03:00 +14 04:00 NaN(缺测) 05:00 +46(跳变待核查) 06:00 −1 非风暴信号核查 量级:整段系统性偏大 → 查基准面/单位 连续性:|ΔR| > 40 cm/h → 标记跳变 周期性:残留半日周期 → 查分潮/时间错位 符号:长期稳定负值 → 查基准面方向 通过 → 进入气压效应分离 关键原则:先对齐、再统一、后相减;缺测不参与计算,跳变先标记后判断,残差通过核查才可用于风暴增水分析。 示例数据为教学假设值,非实测结果

结果判读与通过条件

对示例序列,判读结论如下:01–03 时残差在 +14~+17 cm 之间,量级合理、连续性好,可视为有效原始残差;04 时因实测缺测记为 NaN,不参与后续统计;05 时 +46 cm 被标记为跳变待核查,需回看原始观测曲线——若原始曲线在该时刻确有陡升且 06 时回落,则可能是短时真实增水,否则应作为异常剔除;06 时 −1 cm 属正常范围。

通过条件建议写成三条可执行判据:① 残差序列中缺测点已显式标记为 NaN 且不参与均值/峰值统计;② 相邻时刻残差突变超过阈值(本例 40 cm/h)的点均已标记并给出处理结论;③ 残差序列未呈现系统性偏大或明显半日周期残留。三条同时满足,才可把该残差序列交给下一步的气压效应分离。
常见错误:把缺测时刻按 0 参与相减,会人为制造 −H_pre 的大负残差;把米制观测与厘米制预报直接相减,会得到量级差 100 倍的假残差;忽略时区差异(如观测为世界时、预报为北京时间)会让残差呈现虚假的周期性。这三类错误都会在残差图上表现为“异常”,但根源不在风暴。