求带掩码元素的numpy ndarray的平均值

时间:2018-10-16 19:55:56

标签: python arrays numpy mask

我有一个来自实验的MxN值数组。这些值中的一些无效,并设置为0表示这种情况。我可以使用

构造一个有效/无效值的掩码
mask = (mat1 == 0) & (mat2 == 0)

生成一个MxN布尔数组。应该注意的是,被遮罩的位置并不能整齐地跟随矩阵的行或列-因此,简单地裁剪矩阵是不可行的。

现在,我想沿数组的一个轴取平均值(例如,E以1xN数组结尾),同时在平均值计算中排除那些无效值。我凭直觉认为

 np.mean(mat1[mask],axis=1)

应该这样做,但是mat1[mask]操作会生成一维数组,该数组似乎只是mask为真的元素-当我只希望在数组。

是否有“ python式”或numpy方式来做到这一点?我想我可以使用遮罩将遮罩的元素设置为NaN并使用np.nanmean-但这仍然有点笨拙。有办法“干净”地做到这一点吗?

2 个答案:

答案 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