python 中带有掩码数组的 If 语句
If statements with masked arrays in python
我正在尝试 运行 使用掩码数组的(嵌套条件)程序。我在没有屏蔽数组的情况下使用了相同的函数并且工作正常。该函数如下所示:
import numpy as np
x = np.random.rand(100)
x = x.reshape(4,25)
x = np.ma.masked_less(x,0.2)
y = np.random.rand(100)
y = y.reshape(4,25)
y = np.ma.masked_less(y,0.2)
z = np.zeros_like(x)
#say that both arrays are masked in the same positions.
for i in range(len(x)):
for j in range(len(y)):
if x[i,j] >= y[i,j]:
if (x[i,j]-y[i,j]) > (z[i,j-1]):
z[i,j] = 0.
else:
z[i,j] = 1.
else:
z[i,j] = z[i,j-1] - (x[i,j]-y[i,j])
我确实希望得到一个与输入数据(在本例中为 x,y)具有相同特征(i.e.masked)的数组。但是,我得到的结果是,或者是一个完全屏蔽的数组,或者是一个没有屏蔽的充满值的数组,如下所示:
z =
masked_array(data =
[[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
...,
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]],
mask =
[[ True True True ..., True True True]
[ True True True ..., True True True]
[ True True True ..., True True True]
...,
[ True True True ..., True True True]
[ True True True ..., True True True]
[ True True True ..., True True True]],
fill_value = 9.96920996839e+36)
z =
masked_array(data =
[[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
...,
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]],
mask =
[[False False False ..., False False False]
[False False False ..., False False False]
[False False False ..., False False False]
...,
[False False False ..., False False False]
[False False False ..., False False False]
[False False False ..., False False False]],
fill_value = 9.96920996839e+36)
实际上我想要这样的东西:
z =
masked_array(data =
[[9.0 -- -- ..., -- -- --]
[8.7 -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
...,
[1.0 -- -- ..., -- -- --]
[-- 3.6 -- ..., -- -- --]
[-- -- -- ..., -- -- --]],
mask =
[[ False True True ..., True True True]
[ False True True ..., True True True]
[ True True True ..., True True True]
...,
[ False True True ..., True True True]
[ True False True ..., True True True]
[ True True True ..., True True True]],
fill_value = 9.96920996839e+36)
我已经阅读了有关屏蔽数组的可用信息,以及此处的类似问题,但其中 none 对此有令人满意的解释。我想知道条件语句是否有可能以类似于 numpy.where 的方式工作,因为它们仅显示此类条件的索引?
第二个 if
语句中可能有错字。应该是
for i in range(len(x)):
for j in range(len(y)):
if x[i,j] >= y[i,j]:
if (x[i,j]-y[i,j]) > (z[i,j-1]): # not x - y[i,j], but x[i,j]-y[i,j] ??
# and further down
在我的电脑上,它确实有效并产生了预期的结果,即与 masked/unmasked 混合在一起的掩码数组:
In [2]: z
Out[2]:
masked_array(data =
[[0.34864202355178786 1.0 1.0 1.6118423555903627 -- 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]
[0.32457641778594915 1.0 1.0 -- -- 0.0 -- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0]
[-- 1.0 1.541983077540757 1.0 0.0 0.0 -- 0.0 0.0 0.0 -- 0.0 0.0 -- 0.0 0.0
0.0 0.0 0.0 0.0 0.0 -- 0.0 0.0 --]
[-- -- 1.0 -- 0.0 0.0 0.0 0.0 0.0 -- 0.0 -- 0.0 0.0 0.0 -- 0.0 -- 0.0 --
-- 0.0 0.0 0.0 0.0]],
mask =
[[False False False False True False False False False False False False
False False False False False False False False False False False False
False]
[False False False True True False True False False False False False
False False False False False False False False False False False False
False]
[ True False False False False False True False False False True False
False True False False False False False False False True False False
True]
[ True True False True False False False False False True False True
False False False True False True False True True False False False
False]],
fill_value = 1e+20)
还有另一种计算方法,无需屏蔽数组。
如果你愿意,你仍然可以在最后屏蔽 z
数组。
x = np.random.rand(100)
x = x.reshape(4,25)
y = np.random.rand(100)
y = y.reshape(4,25)
# first if- first if
idxs_1 = ( x >= y) & ((x-y) > (z-1))
z[idxs_1] = 0
# second if-else
idxs_2 = (x>=y) & ((x-y) <= z-1)
z[idxs_2] = 1
# final else
idxs_3 = x < y
idxs_3_p = np.hstack((idxs_3[:, 1:], idxs_3[:,0][:,None])) # reshape so that we shift z by one column left
z[idxs_3] = z[idxs_3_p] - (x[idxs_3] - y[idxs_3])
您需要仔细检查一些测试数据的布尔索引的正确性。
我已经使用 'external' 循环解决了我的问题。我的意思是我在我的核心函数中只使用了一个循环而不是 2 或 3,具体取决于我的数据(1D 到 3D 数组),即
def func(x,y):
import numpy as np
x = np.random.rand(100)
x = x.reshape(4,25)
x = np.ma.masked_less(x,0.2)
y = np.random.rand(100)
y = y.reshape(4,25)
y = np.ma.masked_less(y,0.2)
z = np.zeros_like(x)
#say that both arrays are masked in the same positions.
for i in range(len(x)):
z[i] = x[i] >= y[i]:
if (x[i]-y[i]) > (z[i-1]):
z[i] = 0.
else:
z[i] = 1.
else:
z[i] = z[i-1] - (x[i]-y[i])
return z
然后,如果我有一个 3D 阵列 netCDF 文件,我将我的函数应用为:
func = np.zeros_like(x)
for i in range(len(x)):
for j in range(len(y)):
func[i,j] = func(x[i,j],x[i,j])
请注意,使用 numpy.where 也是一个不错且更快的选择。但是,由于我在 python(和一般编程)方面的经验不多,我没有利用 numpy 机器来向量化我的函数。现在,我的功能似乎按预期工作。
我正在尝试 运行 使用掩码数组的(嵌套条件)程序。我在没有屏蔽数组的情况下使用了相同的函数并且工作正常。该函数如下所示:
import numpy as np
x = np.random.rand(100)
x = x.reshape(4,25)
x = np.ma.masked_less(x,0.2)
y = np.random.rand(100)
y = y.reshape(4,25)
y = np.ma.masked_less(y,0.2)
z = np.zeros_like(x)
#say that both arrays are masked in the same positions.
for i in range(len(x)):
for j in range(len(y)):
if x[i,j] >= y[i,j]:
if (x[i,j]-y[i,j]) > (z[i,j-1]):
z[i,j] = 0.
else:
z[i,j] = 1.
else:
z[i,j] = z[i,j-1] - (x[i,j]-y[i,j])
我确实希望得到一个与输入数据(在本例中为 x,y)具有相同特征(i.e.masked)的数组。但是,我得到的结果是,或者是一个完全屏蔽的数组,或者是一个没有屏蔽的充满值的数组,如下所示:
z =
masked_array(data =
[[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
...,
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]],
mask =
[[ True True True ..., True True True]
[ True True True ..., True True True]
[ True True True ..., True True True]
...,
[ True True True ..., True True True]
[ True True True ..., True True True]
[ True True True ..., True True True]],
fill_value = 9.96920996839e+36)
z =
masked_array(data =
[[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
...,
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]
[9.0 9.0 9.0 ..., 9.0 9.0 9.0]],
mask =
[[False False False ..., False False False]
[False False False ..., False False False]
[False False False ..., False False False]
...,
[False False False ..., False False False]
[False False False ..., False False False]
[False False False ..., False False False]],
fill_value = 9.96920996839e+36)
实际上我想要这样的东西:
z =
masked_array(data =
[[9.0 -- -- ..., -- -- --]
[8.7 -- -- ..., -- -- --]
[-- -- -- ..., -- -- --]
...,
[1.0 -- -- ..., -- -- --]
[-- 3.6 -- ..., -- -- --]
[-- -- -- ..., -- -- --]],
mask =
[[ False True True ..., True True True]
[ False True True ..., True True True]
[ True True True ..., True True True]
...,
[ False True True ..., True True True]
[ True False True ..., True True True]
[ True True True ..., True True True]],
fill_value = 9.96920996839e+36)
我已经阅读了有关屏蔽数组的可用信息,以及此处的类似问题,但其中 none 对此有令人满意的解释。我想知道条件语句是否有可能以类似于 numpy.where 的方式工作,因为它们仅显示此类条件的索引?
第二个
if
语句中可能有错字。应该是for i in range(len(x)): for j in range(len(y)): if x[i,j] >= y[i,j]: if (x[i,j]-y[i,j]) > (z[i,j-1]): # not x - y[i,j], but x[i,j]-y[i,j] ?? # and further down
在我的电脑上,它确实有效并产生了预期的结果,即与 masked/unmasked 混合在一起的掩码数组:
In [2]: z Out[2]: masked_array(data = [[0.34864202355178786 1.0 1.0 1.6118423555903627 -- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0] [0.32457641778594915 1.0 1.0 -- -- 0.0 -- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0] [-- 1.0 1.541983077540757 1.0 0.0 0.0 -- 0.0 0.0 0.0 -- 0.0 0.0 -- 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -- 0.0 0.0 --] [-- -- 1.0 -- 0.0 0.0 0.0 0.0 0.0 -- 0.0 -- 0.0 0.0 0.0 -- 0.0 -- 0.0 -- -- 0.0 0.0 0.0 0.0]], mask = [[False False False False True False False False False False False False False False False False False False False False False False False False False] [False False False True True False True False False False False False False False False False False False False False False False False False False] [ True False False False False False True False False False True False False True False False False False False False False True False False True] [ True True False True False False False False False True False True False False False True False True False True True False False False False]], fill_value = 1e+20)
还有另一种计算方法,无需屏蔽数组。
如果你愿意,你仍然可以在最后屏蔽 z
数组。
x = np.random.rand(100)
x = x.reshape(4,25)
y = np.random.rand(100)
y = y.reshape(4,25)
# first if- first if
idxs_1 = ( x >= y) & ((x-y) > (z-1))
z[idxs_1] = 0
# second if-else
idxs_2 = (x>=y) & ((x-y) <= z-1)
z[idxs_2] = 1
# final else
idxs_3 = x < y
idxs_3_p = np.hstack((idxs_3[:, 1:], idxs_3[:,0][:,None])) # reshape so that we shift z by one column left
z[idxs_3] = z[idxs_3_p] - (x[idxs_3] - y[idxs_3])
您需要仔细检查一些测试数据的布尔索引的正确性。
我已经使用 'external' 循环解决了我的问题。我的意思是我在我的核心函数中只使用了一个循环而不是 2 或 3,具体取决于我的数据(1D 到 3D 数组),即
def func(x,y):
import numpy as np
x = np.random.rand(100)
x = x.reshape(4,25)
x = np.ma.masked_less(x,0.2)
y = np.random.rand(100)
y = y.reshape(4,25)
y = np.ma.masked_less(y,0.2)
z = np.zeros_like(x)
#say that both arrays are masked in the same positions.
for i in range(len(x)):
z[i] = x[i] >= y[i]:
if (x[i]-y[i]) > (z[i-1]):
z[i] = 0.
else:
z[i] = 1.
else:
z[i] = z[i-1] - (x[i]-y[i])
return z
然后,如果我有一个 3D 阵列 netCDF 文件,我将我的函数应用为:
func = np.zeros_like(x)
for i in range(len(x)):
for j in range(len(y)):
func[i,j] = func(x[i,j],x[i,j])
请注意,使用 numpy.where 也是一个不错且更快的选择。但是,由于我在 python(和一般编程)方面的经验不多,我没有利用 numpy 机器来向量化我的函数。现在,我的功能似乎按预期工作。