简单的问题:我不仅想要最大值的值,还想要它在 xarray DataArray 中的坐标。怎么做?
当然,我可以编写自己的简单 reduce 函数,但我想知道 xarray 中是否内置了任何东西?
简单的问题:我不仅想要最大值的值,还想要它在 xarray DataArray 中的坐标。怎么做?
当然,我可以编写自己的简单 reduce 函数,但我想知道 xarray 中是否内置了任何东西?
更新:
xarray 现在具有idxmax
选择沿一维的最大值坐标的方法:
In [8]: da = xr.DataArray(
...: np.random.rand(2,3),
...: dims=list('ab'),
...: coords=dict(a=list('xy'), b=list('ijk'))
...: )
In [14]: da
Out[14]:
<xarray.DataArray (a: 2, b: 3)>
array([[0.63059257, 0.00155463, 0.60763418],
[0.19680788, 0.43953352, 0.05602777]])
Coordinates:
* a (a) <U1 'x' 'y'
* b (b) <U1 'i' 'j' 'k'
In [13]: da.idxmax('a')
Out[13]:
<xarray.DataArray 'a' (b: 3)>
array(['x', 'y', 'x'], dtype=object)
Coordinates:
* b (b) <U1 'i' 'j' 'k'
但是,以下答案仍然与多个维度上的最大值相关。
您可以使用da.where()
基于最大值进行过滤:
In [17]: da = xr.DataArray(
np.random.rand(2,3),
dims=list('ab'),
coords=dict(a=list('xy'), b=list('ijk'))
)
In [18]: da.where(da==da.max(), drop=True).squeeze()
Out[18]:
<xarray.DataArray ()>
array(0.96213673)
Coordinates:
a <U1 'x'
b <U1 'j'
编辑:更新示例以更清楚地显示索引,现在 xarray 没有默认索引
一个方法在 xarray 中idxmax()
会很受欢迎,但还没有人开始实施它。
argmax
现在,您可以通过组合和找到最大值的坐标isel
:
>>> array = xarray.DataArray(
... [[1, 2, 3], [3, 2, 1]],
... dims=['x', 'y'],
... coords={'x': [1, 2], 'y': ['a', 'b', 'c']})
>>> array
<xarray.DataArray (x: 2, y: 3)>
array([[1, 2, 3],
[3, 2, 1]])
Coordinates:
* x (x) int64 1 2
* y (y) <U1 'a' 'b' 'c'
>>> array.isel(y=array.argmax('y'))
<xarray.DataArray (x: 2)>
array([3, 3])
Coordinates:
* x (x) int64 1 2
y (x) <U1 'c' 'a'
这可能是.max()
每种情况下都应该做的!不幸的是,我们还没有完全做到。
问题是它还没有按照我们想要的方式在多个维度上推广到最大值:
>>> array.argmax() # what??
<xarray.DataArray ()>
array(2)
问题是它会自动变平,例如np.argmax
. 相反,我们可能想要一个元组数组或数组元组之类的东西,指示最大值的原始整数坐标。对此的贡献也将受到欢迎——有关更多详细信息,请参阅此问题。
您还可以使用堆栈:
假设数据是一个具有时间、经度、纬度的 3d 变量,并且您想要通过时间的最大值的坐标。
stackdata = data.stack(z=('lon', 'lat'))
maxi = stackdata.argmax(axis=1)
maxipos = stackdata['z'][maxi]
lonmax = [maxipos.values[itr][0] for itr in range(ntime)]
latmax = [maxipos.values[itr][1] for itr in range(ntime)]
这将返回 xarray 数据数组中最大值的坐标点。
max = xarraydata.where(xarraydata==xarraydata.max(), drop=True).squeeze()