沿水平变量的矢量化选择

Vectorized selection along level variable

构建 DataArray 时,我可以方便地 select 沿着某个坐标:

import xarray as xr

d = xr.DataArray([1, 2, 3],
                 coords={'c': ['a', 'b', 'c']},
                 dims=['c'])
d.sel(c='a')

甚至沿该坐标上的多个值:

d.sel(c=['a', 'b'])

但是,一旦坐标是多索引维度的一部分,这将无法工作:

d = xr.DataArray([1, 2, 3],
                 coords={'c': ('multi_index', ['a', 'b', 'c']), 
                         'd': ('multi_index', ['x', 'y', 'z'])},
                 dims=['multi_index'])
d.sel(c='a')  # error
d.sel(c=['a', 'b'])  # error

错误 ValueError: dimensions or multi-index levels ['c'] do not exist。 我在尝试执行此操作时看到的另一个错误消息是 ValueError: Vectorized selection is not available along level variable。 似乎只能 select 沿维度。 当单个维度包含大量元数据并且人们只想 select 基于单个元数据坐标的值时,这就变得困难了。

除了手动对事物进行位置索引之外,是否有建议的解决方法?

swap_dims 做了一些解决方法。

In [8]: d.swap_dims({'multi_index': 'c'}).sel(c=['a', 'b'])
Out[8]: 
<xarray.DataArray (c: 2)>
array([1, 2])
Coordinates:
  * c        (c) <U1 'a' 'b'
    d        (c) <U1 'a' 'b'

其中 'c' 成为维度而不是 'multi_index'。

如果您想 select 基于 'c' 和 'd' 以随机方式,使用 MultiIndex 可能是合适的。 set_index 这样做,

In [12]: d.set_index(cd=['c', 'd'])
Out[12]: 
<xarray.DataArray (multi_index: 3)>
array([1, 2, 3])
Coordinates:
  * cd       (cd) MultiIndex
  - c        (cd) object 'a' 'b' 'c'
  - d        (cd) object 'a' 'b' 'c'
Dimensions without coordinates: multi_index

In [13]: d.set_index(cd=['c', 'd']).sel(c='b')
Out[13]: 
<xarray.DataArray (multi_index: 3)>
array([1, 2, 3])
Coordinates:
  * d        (d) object 'b'
Dimensions without coordinates: multi_index

但是,MultiIndex 尚不支持矢量化 selection, (会报错ValueError: Vectorized selection is not available along level variable

也许第一个选项更适合您的用例。