简介:这份资源面向气象、海洋与气候数据分析的入门学习者,提供来自Met Office Hadley Centre观测数据集的全球海水表面温度与海冰浓度数据,均为nc格式,并附带一份入门级Python处理代码,帮助读者快速了解变量结构与数据组织方式,解决初次接触HadISST数据时不知从何下手的问题。压缩包为7z格式,共3个文件,包含2个nc数据文件与1个py脚本,整体约167.98MB,nc文件承载海温与海冰浓度两类核心变量,py脚本则用于读取并查看变量情况,便于理解数据构造。目前已有4930人学习下载,说明该数据在气候分析入门场景中具有一定参考价值。读者可借助脚本直接查看变量维度、时间范围与数值分布,为后续海温异常分析、海冰范围统计或气候趋势研究打下基础,适合作为Met Office数据处理的起步练习材料。
1. 拿到这份 2020a 海温与海冰数据集,先搞清楚它能干什么
如果你正在做海气相互作用、极地海冰季节变化,或者只是需要一份靠谱的全球海表温度(SST)与海冰浓度(Sea Ice Concentration, SIC)格点场来跑通某个诊断脚本,那这份「全球海水表面温度和海冰浓度数据集(2020a 专用)」大概率就是你要找的东西。它属于典型的 Met Office 风格再分析/观测融合产品,空间覆盖全球,时间切片锁定在 2020a 这个版本周期,变量就是两个核心:SST 和海冰浓度。很多人第一次拿到手会懵——文件命名像密码,维度顺序和常规 NetCDF 不一样,缺测值填充也有一套自己的规矩。这篇笔记就按我实际拆包、写脚本、跑出图的顺序,把「怎么读、怎么裁、怎么算、怎么避坑」一次讲透。适合已经会一点 Python 或 CDO,但不想在格式转换上浪费一整天的人。
2. 读懂 2020a 的存储结构:维度、变量与缺测值约定
2.1 先确认文件格式与维度顺序
这份数据集常见分发格式是 NetCDF(部分镜像可能给的是压缩包内多个 .nc)。不要急着 xarray.open_dataset 一把梭,先看维度。Met Office 系产品经常把时间维放在最前,但纬度方向可能是从北到南递减,也可能是 -90 到 90 递增。海冰浓度通常还有一层 land mask,SST 在陆地上是缺测。我一般先用 ncdump -h 扫一眼头信息,确认维度名和变量名。
# 查看 NetCDF 头信息,确认维度顺序和变量名 ncdump -h sst_ice_2020a.nc | head -60逻辑说明:ncdump -h 只输出元数据,不读数据体,速度快。重点看 dimensions 里 time、lat、lon 的大小,以及 variables 里 SST、SIC 的 _FillValue 和 scale_factor。参数说明:如果变量名不是 sst/sic 而是 analysed_sst/sea_ice_fraction,后面代码要对应改。
2.2 缺测值与单位换算的坑
SST 常见单位是开尔文(K),但有些衍生文件已经转成摄氏度。海冰浓度是 0 到 1 的分数,不是百分比。缺测值通常用 1e30 或 -9999 填充。如果你直接算全球平均,缺测值会把结果拉到离谱。我习惯在读取后立刻做掩膜。
import xarray as xr import numpy as np ds = xr.open_dataset('sst_ice_2020a.nc') # 查看变量名和属性 print(ds.data_vars) print(ds['sst'].attrs) # 确认 units 和 _FillValue # 假设变量名为 sst 和 sic sst = ds['sst'].where(ds['sst'] < 1e30) # 把异常大值设为 NaN sic = ds['sic'].where(ds['sic'] <= 1.0) # 海冰浓度不应超过 1 # 如果 units 是 K,转摄氏度 if ds['sst'].attrs.get('units') == 'K': sst = sst - 273.15逻辑说明:where 条件把缺测和越界值变成 NaN,后续 mean 会自动跳过 NaN。参数说明:1e30 是常见缺测阈值,但最好从 attrs['_FillValue'] 读取;海冰浓度上限 1.0 用于剔除填充错误。
2.3 经纬度网格与区域裁剪
全球网格分辨率常见是 0.25° 或 1°。如果你只关心某个海域,比如北大西洋或南极威德尔海,用 sel 做切片比重新插值快得多。注意纬度顺序:如果 lat 是从 90 到 -90,切片时要用 slice(60, 20) 这种降序写法。
# 裁剪北大西洋区域:纬度 20N-60N,经度 -80W 到 0 sst_na = sst.sel(lat=slice(60, 20), lon=slice(-80, 0)) # 如果经度是 0-360,则用 slice(280, 360)逻辑说明:sel 按标签切片,不改变网格。参数说明:先 print(ds.lat.values[:5]) 确认方向,避免切出空数组。
3. 用 Python 和 CDO 做基础处理:从日平均到月平均
3.1 时间维解析与重采样
2020a 的时间坐标可能是 datetime64,也可能是「days since 1981-01-01」这类偏移。xarray 一般能自动解码,但如果失败,需要手动指定 units。做月平均用 resample 最稳。
# 确保时间维可解析 ds = xr.decode_cf(ds) # 计算月平均 SST sst_monthly = sst.resample(time='1MS').mean(dim='time') # 1MS 表示每月第一天为标签,避免月末偏移逻辑说明:resample 按时间分组求平均,自动跳过 NaN。参数说明:'1MS' 是 month start 频率,比 'M' 更规整;如果数据是逐日,也可以先用 groupby('time.month').mean()。
3.2 用 CDO 快速算气候态和异常
如果你不想写 Python,CDO 一行顶十行。前提是文件变量名规范。先看 CDO 能不能识别。
# 查看文件信息 cdo sinfo sst_ice_2020a.nc # 计算海冰浓度的月平均 cdo monmean -selname,sic sst_ice_2020a.nc sic_monmean.nc # 计算 SST 的 2020 年全年平均 cdo yearmean -selname,sst sst_ice_2020a.nc sst_yearmean.nc逻辑说明:-selname 先选变量,避免多变量干扰。参数说明:monmean 输出每月一个时次;yearmean 输出全年一个时次。如果变量名不是 sic/sst,用 cdo showname 查。
3.3 海冰浓度与 SST 的联合掩膜
做诊断时经常需要「无冰海域的 SST」或者「有冰区域的 SIC」。直接相乘或 where 组合即可。
# 只保留海冰浓度大于 0.15 的区域(常见冰边缘阈值) sst_ice_edge = sst.where(sic > 0.15) # 计算无冰海域平均 SST sst_open_water = sst.where(sic < 0.15) mean_open = sst_open_water.mean(dim=['lat', 'lon'])逻辑说明:where 保留满足条件的值,其余为 NaN。参数说明:0.15 是冰边缘常用阈值,可按研究习惯改 0.2 或 0.3。
4. 避坑与排查:这份数据集最容易翻车的五个地方
4.1 现象:全球平均 SST 算出来是 300 多度
原因:单位是开尔文,没转摄氏度,或者缺测值 1e30 没掩膜。 解决:先检查 attrs['units'],再 where 掉大于 100 的值。
4.2 现象:海冰浓度出现 1.5 或负值
原因:scale_factor 和 add_offset 没应用,或者填充值被当成有效值。 解决:用 xarray.decode_cf 自动缩放,或手动 ds['sic'] * scale + offset。
4.3 现象:区域裁剪后数组为空
原因:纬度顺序是降序,slice 写反了。 解决:print(ds.lat.values[:5]) 确认方向,降序用 slice(高, 低)。
4.4 现象:CDO 报「变量未找到」
原因:变量名是 analysed_sst 而不是 sst。 解决:cdo showname 列出所有变量名,再用 -selname 指定。
4.5 现象:月平均结果时间标签错位
原因:用了 'M' 而不是 '1MS',标签落在月末。 解决:统一用 resample(time='1MS') 或 CDO 的 monmean。
5. 进阶技巧:把 2020a 数据接入自己的诊断流程
5.1 导出为 CSV 做快速绘图
如果你只想画几条时间序列,导出 CSV 比 NetCDF 轻量。
# 提取某个格点的 SST 时间序列 point = sst.sel(lat=30, lon=-40, method='nearest') df = point.to_dataframe().reset_index() df[['time', 'sst']].to_csv('sst_point.csv', index=False)逻辑说明:method='nearest' 避免精确匹配失败。参数说明:lat/lon 按实际网格取最近点。
5.2 用 xarray 做多年对比的注意事项
2020a 只是单年版本,如果你想和气候态对比,需要额外下载多年数据。常见做法是算 1981-2010 气候态,再减。但注意:不同版本的海冰算法可能有差异,直接相减会引入系统偏差。我一般会先检查两个文件的网格是否一致,不一致先用 cdo remapbil 统一。
# 把 2020a 数据插值到气候态网格 cdo remapbil,clim_grid.txt sst_ice_2020a.nc sst_ice_2020a_regrid.nc逻辑说明:remapbil 双线性插值,适合连续变量。参数说明:clim_grid.txt 是目标网格描述文件,可用 cdo griddes 从气候态文件生成。
5.3 验证数据质量的一个小习惯
每次处理完,我会强制画一张全球 SST 和 SIC 的 quick look,检查有没有异常条带、缺测区域是否合理。这一步救过我很多次——有一次发现某个月份海冰浓度全为缺测,原因是下载不完整。从那以后我每次拿到新文件都先跑一遍 ncdump 和快速出图,确认数据完整再往下做。希望帮到你。
本文还有配套的精品资源,点击获取