仍在访问 numpy 掩码数组填充值
numpy masked array fill value still being accessed
我正在尝试将图像处理为掩码数组以处理 NoData 区域。我决定先对一维数组进行一些测试,结果发现有些奇怪。这是我的测试代码:
a = np.array([0,1,4,3,4,-9999,33,34,-9999])
am = np.ma.MaskedArray(a)
am.mask = (am==-9999)
z = np.arange(35)
z[am]
我希望用屏蔽数组索引 z 数组会成功,但我看到以下错误:
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
IndexError: index -9999 is out of bounds for size 35
任何人都可以评论如何正确编码吗?我可以 运行 成功执行以下命令:
z[a[a>0]]
这实际上是一回事。
谢谢!
试试这个代码
a = np.array([0,1,4,3,4,-9999,33,34,-9999])
am = np.ma.MaskedArray(a)
am.mask = (am==-9999)
np.ma.set_fill_value(am, 0)
z = np.arange(35)
print z[am.filled()]
访问am
给出掩码数组,其中掩码值指的是原始值(它只是对原始数组的引用)。设置fill_value后调用am.filled()
替换am.filled
返回的数组中带有 fill_value 的屏蔽元素
为了索引目的使用标记数组通常不是一个好主意,正是因为应该在屏蔽值处发生的行为是未定义的。
这样想:当我查看你的数组 a
和你的数组 z
时,我可以说 "Ok, a[0] = 0
so z[a[0]]
makes sense." 等等,直到遇到 a[5] = -9999
当我可以说 "OK, that can't make sense as an index for z
" 并且可以引发异常时。
这实际上是当您天真地使用 am
作为索引集时会发生的事情...它恢复为使用包含 all 的 am.data
的原始值。相反,如果它尝试使用 [z[i] for i in am]
之类的东西,您会 运行 遇到遇到 numpy.ma.core.MaskedConstant
的问题,这不是索引的合理值 - 不适用于获取value 也不会忽略获取值的请求.
In [39]: l = [x for x in am]
In [40]: l
Out[40]: [0, 1, 4, 3, 4, masked, 33, 34, masked]
In [41]: type(l[-1])
Out[41]: numpy.ma.core.MaskedConstant
(事实上,如果您尝试索引其中一个人,您会得到 IndexError: arrays used as indices must be of integer (or boolean) type
)。
但是现在如果我在 am.filled()
中遇到屏蔽值会怎样? am.filled()
的第 5 个索引处的条目将不是 numpy.ma.core.MaskedConstant
的实例——它将是您选择的任何填充值。如果该填充值作为索引有意义,那么您实际上将通过在该索引处建立索引来获取一个值。以 0 为例。它看起来像是一个无伤大雅的中性填充值,但实际上它代表了一个有效的索引,因此您可以两次额外访问 z
:
的第 0 个条目
In [42]: am.fill_value = 0
In [43]: z[am.filled()]
Out[43]: array([ 0, 1, 4, 3, 4, 0, 33, 34, 0])
这也不是面具应该做的事情!
一个半生不熟的方法是遍历 am
并排除 type
或 np.ma.core.MaskedConstant
:
的任何内容
In [45]: z[np.array([x for x in am if type(x) is not np.ma.core.MaskedConstant])]
Out[45]: array([ 0, 1, 4, 3, 4, 33, 34])
但真正更清晰地表达所有这些是首先使用简单的逻辑索引:
In [47]: z[a[a != -9999]]
Out[47]: array([ 0, 1, 4, 3, 4, 33, 34])
请注意,这样的逻辑索引对二维数组也适用,只要您愿意接受,一旦更高维数组被逻辑索引,如果结果不再符合相同的常规二维形状, 那么它将以一维的形式呈现, 像这样:
In [58]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]])
In [59]: a2
Out[59]:
array([[ 10, -9999, 13],
[-9999, 1, 8],
[ 1, 8, 1]])
In [60]: z2 = np.random.rand(3,3)
In [61]: z2[np.where(a2 != -9999)]
Out[61]:
array([ 0.4739082 , 0.13629442, 0.46547732, 0.87674102, 0.08753297,
0.57109764, 0.39722408])
如果你想要类似蒙版效果的东西,你可以设置等于 NaN
的值(对于 float
数组):
In [66]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]], dtype=np.float)
In [67]: a2
Out[67]:
array([[ 1.00000000e+01, -9.99900000e+03, 1.30000000e+01],
[ -9.99900000e+03, 1.00000000e+00, 8.00000000e+00],
[ 1.00000000e+00, 8.00000000e+00, 1.00000000e+00]])
In [68]: a2[np.where(a2 == -9999)] = np.NaN
In [69]: a2
Out[69]:
array([[ 10., nan, 13.],
[ nan, 1., 8.],
[ 1., 8., 1.]])
这种使用 NaN
的掩蔽形式适用于 NumPy 中的大量矢量化数组计算,尽管担心首先将基于整数的图像数据转换为浮点数,然后再转换回来可能会很痛苦安全地结束了。
我正在尝试将图像处理为掩码数组以处理 NoData 区域。我决定先对一维数组进行一些测试,结果发现有些奇怪。这是我的测试代码:
a = np.array([0,1,4,3,4,-9999,33,34,-9999])
am = np.ma.MaskedArray(a)
am.mask = (am==-9999)
z = np.arange(35)
z[am]
我希望用屏蔽数组索引 z 数组会成功,但我看到以下错误:
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
IndexError: index -9999 is out of bounds for size 35
任何人都可以评论如何正确编码吗?我可以 运行 成功执行以下命令:
z[a[a>0]]
这实际上是一回事。
谢谢!
试试这个代码
a = np.array([0,1,4,3,4,-9999,33,34,-9999])
am = np.ma.MaskedArray(a)
am.mask = (am==-9999)
np.ma.set_fill_value(am, 0)
z = np.arange(35)
print z[am.filled()]
访问am
给出掩码数组,其中掩码值指的是原始值(它只是对原始数组的引用)。设置fill_value后调用am.filled()
替换am.filled
为了索引目的使用标记数组通常不是一个好主意,正是因为应该在屏蔽值处发生的行为是未定义的。
这样想:当我查看你的数组 a
和你的数组 z
时,我可以说 "Ok, a[0] = 0
so z[a[0]]
makes sense." 等等,直到遇到 a[5] = -9999
当我可以说 "OK, that can't make sense as an index for z
" 并且可以引发异常时。
这实际上是当您天真地使用 am
作为索引集时会发生的事情...它恢复为使用包含 all 的 am.data
的原始值。相反,如果它尝试使用 [z[i] for i in am]
之类的东西,您会 运行 遇到遇到 numpy.ma.core.MaskedConstant
的问题,这不是索引的合理值 - 不适用于获取value 也不会忽略获取值的请求.
In [39]: l = [x for x in am]
In [40]: l
Out[40]: [0, 1, 4, 3, 4, masked, 33, 34, masked]
In [41]: type(l[-1])
Out[41]: numpy.ma.core.MaskedConstant
(事实上,如果您尝试索引其中一个人,您会得到 IndexError: arrays used as indices must be of integer (or boolean) type
)。
但是现在如果我在 am.filled()
中遇到屏蔽值会怎样? am.filled()
的第 5 个索引处的条目将不是 numpy.ma.core.MaskedConstant
的实例——它将是您选择的任何填充值。如果该填充值作为索引有意义,那么您实际上将通过在该索引处建立索引来获取一个值。以 0 为例。它看起来像是一个无伤大雅的中性填充值,但实际上它代表了一个有效的索引,因此您可以两次额外访问 z
:
In [42]: am.fill_value = 0
In [43]: z[am.filled()]
Out[43]: array([ 0, 1, 4, 3, 4, 0, 33, 34, 0])
这也不是面具应该做的事情!
一个半生不熟的方法是遍历 am
并排除 type
或 np.ma.core.MaskedConstant
:
In [45]: z[np.array([x for x in am if type(x) is not np.ma.core.MaskedConstant])]
Out[45]: array([ 0, 1, 4, 3, 4, 33, 34])
但真正更清晰地表达所有这些是首先使用简单的逻辑索引:
In [47]: z[a[a != -9999]]
Out[47]: array([ 0, 1, 4, 3, 4, 33, 34])
请注意,这样的逻辑索引对二维数组也适用,只要您愿意接受,一旦更高维数组被逻辑索引,如果结果不再符合相同的常规二维形状, 那么它将以一维的形式呈现, 像这样:
In [58]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]])
In [59]: a2
Out[59]:
array([[ 10, -9999, 13],
[-9999, 1, 8],
[ 1, 8, 1]])
In [60]: z2 = np.random.rand(3,3)
In [61]: z2[np.where(a2 != -9999)]
Out[61]:
array([ 0.4739082 , 0.13629442, 0.46547732, 0.87674102, 0.08753297,
0.57109764, 0.39722408])
如果你想要类似蒙版效果的东西,你可以设置等于 NaN
的值(对于 float
数组):
In [66]: a2 = np.array([[10, -9999, 13], [-9999, 1, 8], [1, 8, 1]], dtype=np.float)
In [67]: a2
Out[67]:
array([[ 1.00000000e+01, -9.99900000e+03, 1.30000000e+01],
[ -9.99900000e+03, 1.00000000e+00, 8.00000000e+00],
[ 1.00000000e+00, 8.00000000e+00, 1.00000000e+00]])
In [68]: a2[np.where(a2 == -9999)] = np.NaN
In [69]: a2
Out[69]:
array([[ 10., nan, 13.],
[ nan, 1., 8.],
[ 1., 8., 1.]])
这种使用 NaN
的掩蔽形式适用于 NumPy 中的大量矢量化数组计算,尽管担心首先将基于整数的图像数据转换为浮点数,然后再转换回来可能会很痛苦安全地结束了。