使用坐标因变量对 xarray 数据集进行切片

Cla*_*uds 3 dataset slice python-3.x python-xarray

我在 python3 中构建了一个 xarray 数据集,其中包含(time, levels)一天观测期间识别所有云底和云顶的坐标。该变量levels是在给定时间可以识别的云底/云顶的维度。它存储每次的云底/最高高度值。

现在我想选择位于给定高度范围内随时间变化的所有云底和顶部。高度范围由数组bottom_mod和标识top_mod。这些数组具有time维度并包含要选择的高度范围的边缘。

xarray 数据集是cloudStandard_mod_reshaped

Dimensions:     (levels: 8, time: 9600)
Coordinates:
  * levels      (levels) int64 0 1 2 3 4 5 6 7
  * time        (time) datetime64[ns] 2013-04-14 ... 2013-04-14T23:59:51
Data variables:
    cloudTop    (time, levels) float64 nan nan nan nan nan ... nan nan nan nan
    cloudThick  (time, levels) float64 nan nan nan nan nan ... nan nan nan nan
    cloudBase   (time, levels) float64 nan nan nan nan nan ... nan nan nan nan
Run Code Online (Sandbox Code Playgroud)

我尝试在顶部和底部数组标识的范围内选择高度,如下所示:

PBLclouds = cloudStandard_mod_reshaped.sel(levels=slice(bottom_mod[:], top_mod[:]))
Run Code Online (Sandbox Code Playgroud)

但该指令确实只接受切片命令的标量值。

您知道如何使用依赖于坐标的值进行切片吗?

pai*_*ime 7

您可以使用该.where()方法。

提供解决方案的行在2 以下。

1. 首先,创建一些像您一样的数据:

数据集:

nlevels, ntime = 8, 50

ds = xr.Dataset(
    coords=dict(levels=np.arange(nlevels), time=np.arange(ntime),),
    data_vars=dict(
        cloudTop=(("levels", "time"), np.random.randn(nlevels, ntime)),
        cloudThick=(("levels", "time"), np.random.randn(nlevels, ntime)),
        cloudBase=(("levels", "time"), np.random.randn(nlevels, ntime)),
    ),
)
Run Code Online (Sandbox Code Playgroud)

输出print(ds)

<xarray.Dataset>
Dimensions:     (levels: 8, time: 50)
Coordinates:
  * levels      (levels) int64 0 1 2 3 4 5 6 7
  * time        (time) int64 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49
Data variables:
    cloudTop    (levels, time) float64 0.08375 0.04721 0.9379 ... 0.04877 2.339
    cloudThick  (levels, time) float64 -0.6441 -0.8338 -1.586 ... -1.026 -0.5652
    cloudBase   (levels, time) float64 -0.05004 -0.1729 0.7154 ... 0.06507 1.601
Run Code Online (Sandbox Code Playgroud)

对于顶部和底部级别,我将使底部级别随机并仅添加偏移量来构造顶部级别。

offset = 3

bot_mod = xr.DataArray(
    dims=("time"),
    coords=dict(time=np.arange(ntime)),
    data=np.random.randint(0, nlevels - offset, ntime),
    name="bot_mod",
)

top_mod = (bot_mod + offset).rename("top_mod")
Run Code Online (Sandbox Code Playgroud)

输出print(bot_mod)

<xarray.DataArray 'bot_mod' (time: 50)>
array([0, 1, 2, 2, 3, 1, 2, 1, 0, 2, 1, 3, 2, 0, 2, 4, 3, 3, 2, 1, 2, 0,
       2, 2, 0, 1, 1, 4, 1, 3, 0, 4, 0, 4, 4, 0, 4, 4, 1, 0, 3, 4, 4, 3,
       3, 0, 1, 2, 4, 0])
Run Code Online (Sandbox Code Playgroud)

2. 然后,选择云所在的级别范围:

使用.where()方法选择底层和顶层之间的数据集变量:

ds_clouds = ds.where((ds.levels > bot_mod) & (ds.levels < top_mod))
Run Code Online (Sandbox Code Playgroud)

输出print(ds_clouds)

<xarray.Dataset>
Dimensions:     (levels: 8, time: 50)
Coordinates:
  * levels      (levels) int64 0 1 2 3 4 5 6 7
  * time        (time) int64 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49
Data variables:
    cloudTop    (levels, time) float64 nan nan nan nan nan ... nan nan nan nan
    cloudThick  (levels, time) float64 nan nan nan nan nan ... nan nan nan nan
    cloudBase   (levels, time) float64 nan nan nan nan nan ... nan nan nan nan
Run Code Online (Sandbox Code Playgroud)

它把nan条件不满足的地方,你可以用.dropna()方法去掉那些。

3. 检查是否成功:

cloudBase绘制处理前后数据集的变量:

fig, axes = plt.subplots(ncols=2)

ds.cloudBase.plot.imshow(ax=axes[0])
ds_clouds.cloudBase.plot.imshow(ax=axes[1])

plt.show()
Run Code Online (Sandbox Code Playgroud)

我还不允许嵌入图像,所以这是一个链接:

原始数据与选定数据