(n + 1)-dim布尔屏蔽n-dim数组,其中包含所需输出的均值数组

时间:2016-03-07 13:30:21

标签: 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))])

是否有更有效的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

您可以将matrix-multplicationnp.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.nanminnp.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))