2. 海洋盐度数据获取与格式解析
海洋盐度数据在进入质控流程之前,必须先完成“读得进、看得懂、对得上”三件事:把文件读成内存中的数组,把元数据与坐标解析清楚,再对数据完整性做初步评估。盐度观测来源多样——CTD剖面、Argo浮标、走航ADCP附带温盐、卫星遥感反演、再分析产品——它们落地的格式也各不相同。本节以最常见的 NetCDF、CSV、JSON 三类格式为主线,讲清楚读取方法、元数据检查要点、时间与空间坐标系解析,以及完整性初评的判断依据。
一、三类格式的定位与读取方式
NetCDF 是海洋盐度数据的主力格式,Argo、WOA、CMEMS、HYCOM 等产品几乎都以它分发。它的核心优势是“自描述”:变量、维度、单位、缺测值、坐标轴都写在文件头里。Python 中常用 netCDF4 或 xarray 读取。以 Argo 盐度剖面为例,典型读取代码如下:
import xarray as xr
ds = xr.open_dataset("R5900001_001.nc")
print(ds) # 查看维度、变量、坐标
psal = ds["PSAL"] # 实用盐度,单位 PSU
print(psal.dims, psal.attrs) # ('N_LEVELS',) 及 units、_FillValue
print(ds["TIME"].attrs) # 时间单位与参考历元
CSV 多用于台站观测、航次摘录、教学数据集或质控后导出表。它没有自描述能力,列名、单位、缺测标记全靠约定,因此读取时必须显式声明缺测值并检查列名一致性:
import pandas as pd
df = pd.read_csv("station_salinity.csv",
na_values=["-999", "NaN", ""],
parse_dates=["time_utc"])
print(df.dtypes)
print(df["salinity_psu"].describe())
JSON 常见于浮标实时上报、API 接口返回和部分业务系统交换。它天然嵌套,坐标与观测值可能分层存放,需要先展开再转成表结构:
import json, pandas as pd
with open("buoy_2024.json") as f:
raw = json.load(f)
records = raw["observations"] # 列表,每项含 time/lon/lat/salinity
df = pd.json_normalize(records)
三种格式的读取难点不同:NetCDF 难在维度语义与坐标轴识别,CSV 难在单位与缺测约定,JSON 难在结构展开与字段命名不统一。读取完成后都应立即打印形状、类型和属性,而不是直接进入计算。
二、元数据检查:先看“说明书”再看数据
盐度数据的元数据检查至少覆盖五项:变量单位(PSU、1e-3、g/kg 还是无量纲)、缺测值(_FillValue 或 missing_value)、有效范围、坐标轴定义、数据来源与版本。单位混淆是盐度质控中最常见的隐性错误——把 1e-3 当 PSU、把 g/kg 当 PSU,数值上差异虽小,但在异常判定阈值附近足以改变结论。缺测值若未声明,-999 会被当作真实盐度参与统计,直接污染均值与极值。
三、时间与空间坐标系解析
时间坐标最常见的坑是“单位字符串 + 参考历元”的编码方式,例如 units = "days since 1950-01-01 00:00:00 UTC"。数值 27000 本身没有意义,必须结合 units 才能还原为真实时刻。xarray 通常能自动解码,但遇到非标准 calendar(如 360_day、noleap)或缺失 units 时,需要手动处理。此外要区分观测时间与剖面浮标的上浮时间、卫星过境时间,避免把不同时间基准混用。
空间坐标要确认三件事:经纬度范围与正负号约定(东经为正、北纬为正)、经度是否 0–360 与 -180–180 混用、深度轴方向(positive="down" 表示数值向下增大)。盐度剖面若深度轴方向搞反,表层与底层会被颠倒,异常识别将完全失效。对网格产品还要确认经纬度是格点中心还是格点边界。
四、数据完整性初步评估
完整性初评不是精细质控,而是在进入异常识别前先筛掉“明显不可用”的数据。建议至少计算四项指标:一是缺测比例,按变量统计 NaN 或 _FillValue 占比,盐度剖面缺测率超过 20% 通常应标记存疑;二是时间连续性,检查相邻记录时间间隔是否出现异常断档(如 Argo 剖面间隔远超 10 天);三是空间覆盖,确认经纬度是否落在合理海域且无越界值(经度 > 360、纬度 > 90 均为非法);四是重复记录,按“时间 + 位置 + 深度”组合键去重,避免同一观测被重复计入统计。
一个可直接套用的初评检查表如下,字段按盐度数据实际需要设定:
| 检查项 | 判断依据(示例阈值) | 处理建议 |
|---|---|---|
| 盐度缺测率 | > 20% 标记存疑,> 50% 退回 | 记录比例,保留原始标记 |
| 单位一致性 | units 为 PSU 或 1e-3 | 缺失或异常时暂停后续计算 |
| 时间断档 | 相邻剖面间隔 > 30 天 | 标记为时间不连续 |
| 经纬度合法性 | 纬度 [-90,90],经度统一到 [-180,180] | 越界值置为缺测并记录 |
| 深度轴方向 | positive 属性与数值趋势一致 | 方向不符时翻转深度轴 |
| 重复记录 | 时间+位置+深度完全重复 | 保留首条,其余标记 |
完成上述步骤后,应形成一条可追溯的记录:文件来源、读取时间、元数据缺失项、坐标解析结果、完整性标记。这条记录是后续盐度异常识别与质控结论的依据——没有它,任何“异常”判断都缺少可复核的起点。实践中常见的问题是跳过元数据检查直接画剖面图,图形看似正常,但单位或深度方向已经错了,异常识别自然失去意义。因此,读取、解析、初评三步应作为固定动作串联执行,而不是可选项。