Numpy (n+;1)-dim布尔掩蔽n-dim数组,其平均值数组作为所需输出

Numpy (n+;1)-dim布尔掩蔽n-dim数组,其平均值数组作为所需输出,numpy,Numpy,我有一个二维数组 values=np.random.rand(3,3) 和一个带有布尔掩码的3D数组 masks = np.random.rand(5,3,3)>0.5 我想要的输出是一个屏蔽值的平均值数组。我可以这样做: np.array([values[masks[i]].mean() for i in range(len(masks))]) 有没有更有效的方法来实现这一点?您可以使用矩阵多应用程序- # Counts of valid mask elements for eac

我有一个二维数组

values=np.random.rand(3,3)
和一个带有布尔掩码的3D数组

masks = np.random.rand(5,3,3)>0.5
我想要的输出是一个屏蔽值的平均值数组。我可以这样做:

np.array([values[masks[i]].mean() for i in range(len(masks))])

有没有更有效的方法来实现这一点?

您可以使用
矩阵多应用程序-

# Counts of valid mask elements for each element in output
counts = masks.sum(axis=(1,2))

# Use matrix multiplication to get sum of elementwise multiplications.
# Then, divide by counts for getting average/mean values as final output.
out = np.dot(masks.reshape(masks.shape[0],-1),values.ravel())/counts
out = np.tensordot(masks,values,axes=([1,2],[0,1]))/counts
out_mean = np.nanmean(nan_masked_values,axis=(1,2))
也可以使用来执行点积,而无需重新整形,如下所示-

# Counts of valid mask elements for each element in output
counts = masks.sum(axis=(1,2))

# Use matrix multiplication to get sum of elementwise multiplications.
# Then, divide by counts for getting average/mean values as final output.
out = np.dot(masks.reshape(masks.shape[0],-1),values.ravel())/counts
out = np.tensordot(masks,values,axes=([1,2],[0,1]))/counts
out_mean = np.nanmean(nan_masked_values,axis=(1,2))

对于涉及
min()
max()
等函数的一般情况,您可以将
广播到与
掩码
形状相同的
3D
阵列版本,并在
位置设置
的元素,否则设置为
NaNs
。然后,您可以使用和之类的函数,允许用户忽略
nan
执行此类操作,从而复制我们所需的行为。因此,我们会-

# Masked array with values being put at True places of masks, otherwise NaNs
nan_masked_values = np.where(masks,values,np.nan)

# For performing .min() use np.nanmin
out_min = np.nanmin(nan_masked_values,axis=(1,2))

# For performing .max() use np.nanmax
out_max = np.nanmax(nan_masked_values,axis=(1,2))
因此,原始的
.mean()
计算可以用类似的方法执行-

# Counts of valid mask elements for each element in output
counts = masks.sum(axis=(1,2))

# Use matrix multiplication to get sum of elementwise multiplications.
# Then, divide by counts for getting average/mean values as final output.
out = np.dot(masks.reshape(masks.shape[0],-1),values.ravel())/counts
out = np.tensordot(masks,values,axes=([1,2],[0,1]))/counts
out_mean = np.nanmean(nan_masked_values,axis=(1,2))

values
不应该是类似于
values=np.random.rand(3,5)
?确实如此。我换了面具。这很有趣,而且涉及到我不熟悉的数学。答案的第二部分更适合我的数学水平。我想计算平均值要慢一些,不是吗?@nicoco是的,对于
mean
计算,如果可能的话,我建议使用第一种方法。不幸的是,我简化了问题。我有4D阵列和5D遮罩,我试图找出我必须更改的值…@nicoco我认为唯一的更改是
axis=(1,2)
将变成
axis=(3,4)