我有一个来自实验的MxN值数组。这些值中的一些无效,并设置为0表示这种情况。我可以使用
构造一个有效/无效值的掩码mask = (mat1 == 0) & (mat2 == 0)
生成一个MxN布尔数组。应该注意的是,被遮罩的位置并不能整齐地跟随矩阵的行或列-因此,简单地裁剪矩阵是不可行的。
现在,我想沿数组的一个轴取平均值(例如,E以1xN数组结尾),同时在平均值计算中排除那些无效值。我凭直觉认为
np.mean(mat1[mask],axis=1)
应该这样做,但是mat1[mask]
操作会生成一维数组,该数组似乎只是mask
为真的元素-当我只希望在数组。
是否有“ python式”或numpy方式来做到这一点?我想我可以使用遮罩将遮罩的元素设置为NaN
并使用np.nanmean
-但这仍然有点笨拙。有办法“干净”地做到这一点吗?
答案 0 :(得分:1)
我认为做到这一点的最佳方法是遵循以下原则:
masked = np.ma.masked_where(mat1 == 0 && mat2 == 0, array_to_mask)
然后用
取平均值masked.mean(axis=1)
答案 1 :(得分:1)
一种类似的笨拙但有效的方法是将数组与掩码相乘,将掩码值设置为零。然后,您当然必须手动除以非掩码值的数量。因此笨拙。但这将适用于整数值数组,关于nan
情况,这还不能说。对于小型和大型阵列,这似乎也是最快的(包括另一个答案中的蒙版阵列解决方案):
import numpy as np
def nanny(mat, mask):
mat = mat.astype(float).copy() # don't mutate the original
mat[~mask] = np.nan # mask values
return np.nanmean(mat, axis=0) # compute mean
def manual(mat, mask):
# zero masked values, divide by number of nonzeros
return (mat*mask).sum(axis=0)/mask.sum(axis=0)
# set up dummy data for testing
N,M = 400,400
mat1 = np.random.randint(0,N,(N,M))
mask = np.random.randint(0,2,(N,M)).astype(bool)
print(np.array_equal(nanny(mat1, mask), manual(mat1, mask))) # True