如何在不删除数据变量的情况下添加另一个维度后删除 xarray 维度

How to remove xarray dimension after adding another without deleting the data variables

我有来自 ECMWF 的数据,读入 xarray 后看起来像这样

Dimensions:     (time: 424, step: 12, latitude: 3, longitude: 2)
Coordinates:
    number      int64 0
  * time        (time) datetime64[ns] 1990-03-01T06:00:00 ... 1993-04-22T18:0...
  * step        (step) timedelta64[ns] 01:00:00 02:00:00 ... 11:00:00 12:00:00
    surface     float64 0.0
  * latitude    (latitude) float64 41.0 40.75 40.5
  * longitude   (longitude) float64 -96.92 -96.67
    valid_time  (time, step) datetime64[ns] 1990-03-01T07:00:00 ... 1993-04-2...
Data variables:
    i10fg       (time, step, latitude, longitude) float32 4.876 4.637 ... 3.959
Attributes:
    GRIB_edition:            1
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2022-04-23T22:18 GRIB to CDM+CF via cfgrib-0.9.9...

我将 timestep 维度堆叠在一起,形成一个名为 forecast 的新维度。然后,我添加了另一个名为 valid 的维度,并将其设置为等于坐标 valid_timevalidfcst 的长度相同,但我现在想删除 fcst 维度。但是,当我这样做时,数据变量也会被删除。有谁知道如何解决这一问题?这是我的示例代码。可能有更好的方法来做我正在做的事情,但我对 xarray 还是很陌生!

ds = ds.stack(fcst=("time", "step")).transpose("fcst", "latitude", "longitude")
ds.expand_dims(valid=ds['valid_time']).drop_dims('fcst')

这给我留下了

<xarray.Dataset>
Dimensions:    (valid: 5088, latitude: 3, longitude: 2)
Coordinates:
  * valid      (valid) datetime64[ns] 1990-03-01T07:00:00 ... 1993-04-23T06:0...
    number     int64 0
    surface    float64 0.0
  * latitude   (latitude) float64 41.0 40.75 40.5
  * longitude  (longitude) float64 -96.92 -96.67
Data variables:
    *empty*

我试过将 valid 设置为索引然后删除 fcst 但它仍然删除了数据变量。

如有任何帮助,我们将不胜感激!

xarray 数据集中的所有变量都必须按命名维度进行索引。您可以使用 ds.reset_index` 删除与维度关联的任何标记坐标,但这不是您想要的。你不能简单地取消一个维度而不丢失用这个维度索引的变量。

来自xarray docs on data structures:

dimension names are always present in the xarray data model: if you do not provide them, defaults of the form dim_N will be created.

相反,您可以使用 swap_dims 将 non-indexing 坐标换成索引坐标。这将在您的数组中切换 valid_timefcst,这样 valid_time 成为索引 fcst 和之前由 fcst 索引的任何变量的维度(i10fg 在你的情况下)。

所以答案是,在堆栈之后但没有 expand_dimsdrop:

ds.swap_dims({'fcst': 'valid_time'}).drop('fcst')