Получить индексы значений True в логическом массиве данных. - PullRequest
0 голосов
/ 20 февраля 2019

Как правильно xarray получить индексы значений True логического массива данных.Я знаю, что в numy way используется np.where, но это неудобно для многомерных массивов:

>>> da = xr.DataArray([0., 1., 2.])
>>> da > 0
<xarray.DataArray (dim_0: 3)>
array([False,  True,  True])
Dimensions without coordinates: dim_0
>>> np.where(da > 0)[0]
array([1, 2])

>>> db = xr.DataArray([[0.,1.,2.],[2.,1.,0.]])
>>> db > 0
<xarray.DataArray (dim_0: 2, dim_1: 3)>
array([[False,  True,  True],
       [ True,  True, False]])
Dimensions without coordinates: dim_0, dim_1
>>> np.where(db > 0)
Out[61]: (array([0, 0, 1, 1]), array([1, 2, 0, 1]))

Мне было интересно, можно ли сделать это более элегантно, используя функциональность xarray.

причина в том, что я хочу выборочно изменять части массива, но, во-первых, это не работает для многомерной логической индексации:

>>> da[da > 0] *= 2
>>> da
<xarray.DataArray (dim_0: 3)>
array([0., 2., 4.])
Dimensions without coordinates: dim_0

>>> db[db > 0] *= 2
Traceback (most recent call last):
    [...]
IndexError: 2-dimensional boolean indexing is not supported. 

Во-вторых, в некоторых случаях я повторно использую логическое значениеDataArray много как индексатор, и я хотел бы посмотреть, смогу ли я избежать накладных расходов при поиске связанных значений индекса.(Я не делал никаких профилировок по этому поводу; поэтому эта причина не столь оправдана.)

1 Ответ

0 голосов
/ 05 марта 2019

Один из подходов, которые я нашел, заключается в использовании stack и unstack:

>>> dc = db.stack(z=('dim_0', 'dim_1'))
>>> dc
<xarray.DataArray (z: 6)>
array([0., 1., 2., 2., 1., 0.])
Coordinates:
  * z        (z) MultiIndex
  - dim_0    (z) int64 0 0 0 1 1 1
  - dim_1    (z) int64 0 1 2 0 1 2

>>> dc[dc > 0] += 2
>>> dc
<xarray.DataArray (z: 6)>
array([0., 3., 4., 4., 3., 0.])
Coordinates:
  * z        (z) MultiIndex
  - dim_0    (z) int64 0 0 0 1 1 1
  - dim_1    (z) int64 0 1 2 0 1 2
>>> dc.unstack('z')
<xarray.DataArray (dim_0: 2, dim_1: 3)>
array([[0., 3., 4.],
       [4., 3., 0.]])
Coordinates:
  * dim_0    (dim_0) int64 0 1
  * dim_1    (dim_1) int64 0 1 2 

Мне еще предстоит проверить влияние на эффективность, но функционально это решает мою проблему.

...