我们说我有一个标准的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
答案 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)