如何用一个分离二维数组部分的向量来创建屏蔽数组?

2024-05-18 08:35:57 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个标准的2dnumpy数组,我们称之为my2darray with values。在这个数组中有两个主要部分。假设对于每一列,都有一个分隔“场景1”和“场景2”的特定行。如何创建表示my2darray顶部和底部的2个掩码数组。例如,我对计算上半部分和下半部分的平均值感兴趣。一个想法是拥有一个与my2darray形状相同的面具,但这看起来像是在浪费内存。有更好的办法吗?假设我有一个向量,其中长度等于my2darray中的行数(在本例中为6),即

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

我使用的是Python2.6和Numpy1.5.0

sample matrix


Tags: 内存标准with场景浪费数组向量感兴趣
1条回答
网友
1楼 · 发布于 2024-05-18 08:35:57

使用^{},我们可以以矢量化的方式创建这样的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)

相关问题 更多 >