在数组上迭代函数

Iterating a function over an array

以不同的方式提出这个问题的标题。

我有一个函数,它采用三维数组并根据特定条件屏蔽数组中的某些元素。见下文:

#function for array masking 
def masc(arr,z):
        return(np.ma.masked_where((arr[:,:,2] <= z+0.05)*(arr[:,:,2] >= z-0.05), arr[:,:,2])) 
    

arr 是 3 维数组,z 是单个值。

我现在想对多个 Z 值进行迭代。这是一个有 2 个 z 值的例子:

masked_array1_1 = masc(xyz,z1)
masked_array1_2 = masc(xyz,z2)

masked_1 = masked_array1_1.mask + masked_array1_2.mask
masked_array1 = np.ma.array(xyz[:,:,2],mask=masked_1)

masked_array1 正是我要找的东西。

我已经开始编写一个 forloop 来在 Z 值的一维数组上迭代它:

mask_1 = xyz[:,:,2]
for i in range(Z_all_dim):
    mask_1 += (masc(xyz,Z_all[i]).mask)

masked_array1 = np.ma.array(xyz[:,:,2], mask = mask_1)

Z_all 是一个包含 7 个唯一 z 值的数组。此代码不起作用(整个数组最终被屏蔽)但我觉得我非常接近。有人看到我做错了什么吗?

您的问题是在循环之前您以 mask_1 = xyz[:,:,2] 开始。将布尔数组添加到浮点数会将布尔值转换为 1 和 0,除非您的浮点数组中有任何 0,否则最终数组将全部为非零值,然后导致每个值都被屏蔽。相反做

mask_1 = masc(xyz, Z_all[0]).mask
for z in Z_all[1:]:
    mask_1 += masc(xyz, z).mask

或者避免任何循环并广播您的操作

# No need to pass it through `np.ma.masked_where` if
# you're just going to extract just the boolean mask
mask = (xyz[...,2,None] <= Z_all + 0.05) * (xyz[...,2,None] >= Z_all - 0.05)
mask = np.any(mask, axis=-1)