1

假设我有一个标准的 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

样本矩阵

4

1 回答 1

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)
于 2016-06-15T10:29:44.667 回答