You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理预报步骤的时间重叠?将观测数据维度转为(time,steps)

解决ERA5观测与ECMWF季节预报的CRPS评估维度匹配问题

我已下载2021年ERA5再分析(reanalysis-era5-pressure-levels,变量observation)和ECMWF季节预报(seasonal-original-pressure-levels,变量forecast)的u、v风分量,计划用properscoring库的**Continuous Ranked Probability Score(CRPS)**评估预报性能。

评估思路是通过xr.apply_ufunc基于number(集合成员)维度,为每个时间、纬度、经度计算CRPS,代码示例如下:

import properscoring as ps

crps = xr.apply_ufunc(
    ps.crps_ensemble,
    observation,
    forecast,
    input_core_dims=[[], ["number"]],
    output_core_dims=[[]],
    vectorize=True,
)

但observation的维度为("time", "latitude", "longitude"),而forecast的维度为("time", "latitude", "longitude", "steps", "number"),二者无法兼容(xr.align(..., join = "exact")因time和steps维度不匹配失败)。需要将observation的time维度转换为("time", "steps")以适配预报数据。

已尝试方案

使用backend_kwargs

在另一项目中,我曾用xr.open_dataset(..., backend_kwargs={"time_dims": ("valid_time",)})让valid_time匹配time维度,但当前项目中valid_time与time + steps存在重叠(比如time=2021-01-01 + steps=36:00:00 > time=2021-01-02),会丢失数据,示例代码:

forecast = xr.open_dataset(
    "data/raw/forecast.grib",
    engine="cfgrib",
    backend_kwargs=dict(time_dims=("valid_time",)),
)
# forecast丢失steps > 24:00:00对应的数据

拼接为新维度

尝试用滚动窗口拼接生成不同steps:为每个日期提取后续36小时作为steps并创建新维度,但既没生成目标维度(可能xr.concat不是正确函数),速度还极慢(两个月数据耗时超6分钟),示例代码:

xr.concat(
    [
        observation.sel(time = slice(date, date + pd.Timedelta("36H")))
        for date in observation.time.values
    ],
    dim = "steps"
)

正确解决方法

核心思路是为观测数据生成与预报数据匹配的(time, steps)维度,即对每个预报初始时间time,找到对应time + steps时刻的观测值,通过广播和索引实现高效匹配。

步骤1:计算预报的有效时间(valid_time)

首先从预报数据中生成每个初始时间+步长对应的有效时间,方便后续匹配观测:

# 生成预报的valid_time维度:time + steps
forecast["valid_time"] = forecast.time + forecast.steps

步骤2:将观测数据重索引到预报的valid_time网格

利用xarray的索引和广播机制,将观测数据扩展为与预报匹配的维度:

# 将observation的time重命名为valid_time,统一匹配字段
obs_valid = observation.rename({"time": "valid_time"})

# 匹配每个预报(time, steps)对应的观测值,自动扩展为(time, latitude, longitude, steps)维度
obs_matched = obs_valid.sel(valid_time=forecast.valid_time)

步骤3:调整维度并计算CRPS

确保观测和预报的维度逻辑对应,调用xr.apply_ufunc计算CRPS:

crps = xr.apply_ufunc(
    ps.crps_ensemble,
    obs_matched,  # 维度:(time, latitude, longitude, steps)
    forecast[["u", "v"]],  # 维度:(time, latitude, longitude, steps, number)
    input_core_dims=[[], ["number"]],
    output_core_dims=[[]],
    vectorize=True,
    dask="parallelized",  # 大数据场景下启用dask并行加速
    output_dtypes=[float],
)

# 最终crps的维度为(time, latitude, longitude, steps)

优化说明

  • 无循环高效匹配:利用xarray的广播索引机制,避免显式循环,速度远快于滚动窗口拼接
  • 完整保留数据:通过valid_time精准匹配,不会因跨天步长丢失数据
  • 支持并行计算:结合dask加载数据,可进一步提升大数据量下的计算效率

内容的提问来源于stack exchange,提问作者Felipe Whitaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:27:47