如何使用分隔二维数组部分的向量创建蒙版数组?

时间:2016-06-15 10:13:36

标签: python numpy masked-array

我们说我有一个标准的2d numpy数组,让我们用值来称它为my2darray。在这个数组中有两个主要部分。让我们对每一列说,有一个特定的行分隔" scenario1"和" scenario2"。我如何创建2个代表my2darray顶部和my2darray底部的蒙版数组。例如,我有兴趣计算上半部分的平均值和下半部分的平均值。一个想法是有一个与my2darray形状相同的面具,但这似乎浪费了记忆。有更好的主意吗?让我们说我有一个向量,其中长度等于my2darray中的行数(在本例中为6),即我有

myvector=np.array([9, 15, 5,7,11,11])

我正在使用带有numpy 1.5.0的python 2.6

sample matrix

1 个答案:

答案 0 :(得分:0)

使用NumPy's broadcasted comparison,我们可以以矢量化方式创建这样的2D蒙版。其余的工作全部围绕第一轴sum-reduction,我们可以从np.einsum获得帮助。因此,我们会有这样的实现 -

N = my2darray.shape[0]
mask = myvector <= np.arange(N)[:,None]
uout = np.true_divide(np.einsum('ij,ij->j',my2darray,~mask),myvector)
lout = np.true_divide(np.einsum('ij,ij->j',my2darray,mask),N-myvector)

运行样本以验证结果 -

In [184]: N = my2darray.shape[0]
     ...: mask = myvector <= np.arange(N)[:,None]
     ...: uout = np.true_divide(np.einsum('ij,ij->j',my2darray,~mask),myvector)
     ...: lout = np.true_divide(np.einsum('ij,ij->j',my2darray,mask),N-myvector)
     ...: 

In [185]: uout
Out[185]: array([ 6. ,  4.6,  4. ,  0. ])

In [186]: [my2darray[:item,i].mean() for i,item in enumerate(myvector)]
Out[186]: [6.0, 4.5999999999999996, 4.0, 0.0] # Loopy version results

In [187]: lout
Out[187]: array([ 5.2       ,  4.        ,  2.66666667,  2.        ])

In [188]: [my2darray[item:,i].mean() for i,item in enumerate(myvector)]
Out[188]: [5.2000000000000002, 4.0, 2.6666666666666665, 2.0] # Loopy version

另一种可能更快的方法是计算上面罩的总和,存储它并从中存储,沿着2D输入数组的整个长度减去沿第一轴的总和。然后可以将其用于计算下部平均值。因此,在我们存储N并计算mask之后,我们会有 -

usum = np.einsum('ij,ij->j',my2darray,~mask)
uout = np.true_divide(usums,myvector)
lout = np.true_divide(my2darray.sum(0) - usums,N-myvector)