(回答主要问题)
你快到了。但是,细微的语法差异在这里会产生很大的不同。一方面,这是使用 “基于值” 掩码过滤 >0 值的解决方案。
# if you want to DROP values which do not suffice a mask condition
first_image_xarray[:,0,0].where(first_image_xarray[:,0,0] > 0, drop=True)
或
# if you want to KEEP values which do not suffice a mask condition as nan
first_image_xarray[:,0,0].where(first_image_xarray[:,0,0] > 0, np.nan)
另一方面,你的尝试没有如你所愿的原因是因为first_image_xarray.x,它指的是数组中元素的索引(在x方向) 而不是引用元素的值。因此,只有输出的第一个元素应该是 nan 而不是 0,因为它不能满足切片 [:,0,0] 中的掩码条件。是的,您正在创建一个 “基于索引” 掩码。
以下小实验(希望如此)阐明了这一关键差异。
假设我们有DataArray,其中仅包含0 和1(尺寸与问题(140,140,96) 的原始帖子(OP)对齐)。首先,让我们像 OP 一样根据 index 对其进行屏蔽:
import numpy as np
import xarray as xr
np.random.seed(0)
# create a DataArray which randomly contains 0 or 1 values
a = xr.DataArray(np.random.randint(0, 2, 140*140*96).reshape((140, 140, 96)), dims=('x', 'y', 'z'))
# with this "index-based" mask, only elements where index of both x and y are 0 are replaced by nan
a.where(a.x + a.y > 0, drop=True)[:,0,0]
Out:
<xarray.DataArray (x: 140)>
array([ nan, 0., 1., 1., 0., 0., 0., 1., 0., 0., 0., 0.,
0., 1., 0., 1., 0., 1., 0., 0., 0., 1., 0., 0.,
1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 0., 1., 1., 1., 1., 1., 1., 1., 0., 1.,
1., 0., 0., 0., 1., 1., 1., 0., 0., 1., 0., 0.,
1., 0., 1., 1., 0., 0., 1., 0., 0., 1., 1., 1.,
0., 0., 0., 1., 1., 0., 1., 0., 1., 1., 0., 0.,
0., 0., 1., 1., 0., 1., 1., 1., 1., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 1., 0., 1., 1., 0., 0.,
0., 0., 1., 0., 1., 0., 0., 0., 0., 1., 0., 1.,
0., 0., 1., 0., 0., 0., 0., 0., 1., 1., 0., 0.,
0., 1., 0., 0., 1., 0., 0., 1.])
Dimensions without coordinates: x
使用上面的掩码,只有x和y的index元素都是0的元素变成nan,其余的根本没有改变或删除.
相比之下,建议的解决方案根据DataArray 元素的值 屏蔽DataArray。
# with this "value-based" mask, all the values which do not suffice the mask condition are dropped
a[:,0,0].where(a[:,0,0] > 0, drop=True)
Out:
<xarray.DataArray (x: 65)>
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1.])
Dimensions without coordinates: x
这会根据DataArray 元素的值成功删除所有不满足掩码条件的值。
(回答附带问题)
至于DataArray中-0和0的起源,从负向或正向舍入到0的值是可能的:在此进行了相关讨论How to eliminate the extra minus sign when rounding negative numbers towards zero in numpy?下面是一个小这种情况的例子。
import numpy as np
import xarray as xr
xr_array = xr.DataArray([-0.1, 0.1])
# you can use either xr.DataArray.round() or np.round() for rounding values of DataArray
xr.DataArray.round(xr_array)
Out:
<xarray.DataArray (dim_0: 2)>
array([-0., 0.])
Dimensions without coordinates: dim_0
np.round(xr_array)
Out:
<xarray.DataArray (dim_0: 2)>
array([-0., 0.])
Dimensions without coordinates: dim_0
附带说明,在 NumPy 数组中获取 -0 的另一种可能性是 numpy.set_printoptions(precision=0),它隐藏在小数点以下,如下所示(但我知道这次不是这种情况,因为您使用的是 DataArray ):
import numpy as np
# default value is precision=8 in ver1.15
np.set_printoptions(precision=0)
np.array([-0.1, 0.1])
Out:
array([-0., 0.])
无论如何,我最好的猜测是,在数据准备和预处理阶段转换为-0 应该是手动和有意的,而不是自动的。
希望这会有所帮助。