Python 用蒙版元素取numpy ndarray的平均值

Python 用蒙版元素取numpy ndarray的平均值,python,arrays,numpy,mask,Python,Arrays,Numpy,Mask,我有一个MxN数组,其中的值取自一个实验。其中一些值无效,设置为0表示该值无效。我可以使用 mask = (mat1 == 0) & (mat2 == 0) 它生成一个布尔的MxN数组。需要注意的是,屏蔽位置并不整齐地跟随矩阵的列或行,因此简单地裁剪矩阵不是一个选项 现在,我想沿着数组的一个轴取平均值(例如,以1xN数组结束),同时排除平均值计算中的无效值。直觉上我认为 np.mean(mat1[mask],axis=1) 应该这样做,但是mat1[mask]操作会生成一个1D数组

我有一个MxN数组,其中的值取自一个实验。其中一些值无效,设置为0表示该值无效。我可以使用

mask = (mat1 == 0) & (mat2 == 0)
它生成一个布尔的MxN数组。需要注意的是,屏蔽位置并不整齐地跟随矩阵的列或行,因此简单地裁剪矩阵不是一个选项

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

 np.mean(mat1[mask],axis=1)
应该这样做,但是
mat1[mask]
操作会生成一个1D数组,它似乎就是
mask
为真的元素-当我只需要数组一维的平均值时,这没有帮助


有没有一种“python式”或numpy的方法可以做到这一点?我想我可以使用mask将蒙版元素设置为
NaN
并使用
np.nanmean
——但这仍然感觉有点笨重。有没有“干净”的方法呢?

我认为最好的方法是:

masked = np.ma.masked_where(mat1 == 0 && mat2 == 0, array_to_mask)
那就用平均数来衡量吧

masked.mean(axis=1)

一种类似的笨拙但有效的方法是将数组与掩码相乘,将掩码值设置为零。当然,您必须手动除以非屏蔽值的数量。因此笨重。但这将适用于整数值数组,这在
nan
案例中是无法描述的。对于小型和大型阵列(包括另一个答案中的屏蔽阵列解决方案),它似乎也是最快的:


工作得很好!我不知道蒙面阵列-谢谢!在处理浮动时,手动方法是什么?@m_power我认为手动版本也适用于浮动。我的动机更多的是,对于float情况,您可以只对无效值使用nans,然后使用
np.nanmean
,这可能会更快,因为它是一个单一的numpy函数调用。但是OP已经知道了这一点,如果你看一下他们问题的最后一部分,这就是为什么我把重点放在集成阵列可能需要的手动版本上。但是,如果您需要在多个位置使用屏蔽数据,那么使用屏蔽数组的公认方法总体上可能会更好。这取决于您的用例。谢谢!我正在使用np.nanmean(对于带有一些NaN的浮点数组),但我想看看是否有更快的方法。@m_power如果您已经有一个浮点数组,我希望
np.nanmean
最快,但无可否认,我没有遇到过这样的问题。该函数似乎是用python实现的,因此如果这真的是您的瓶颈,您可以尝试用较少的检查来完成它的功能:
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