我有这个带有值的二维数组
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))])
是否有更有效的方法来实现这一目标?
答案 0 :(得分:1)
您可以将matrix-multplication
与np.dot
一样使用 -
# 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
也可以使用np.tensordot
来执行点积而不需要重新整形,就像这样 -
out = np.tensordot(masks,values,axes=([1,2],[0,1]))/counts
涉及min()
&等功能的通用案例max()
,您可以将values
广播到与3D
形状相同的masks
数组版本,并将values
的元素设置为True
个位置,否则设为NaNs
。然后,您可以使用np.nanmin
和np.nanmax
等函数,允许用户执行忽略NaNs
的操作,从而复制我们想要的行为。因此,我们会 -
# 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()
计算可以使用np.nanmean
执行,如此 -
out_mean = np.nanmean(nan_masked_values,axis=(1,2))