是否有矢量化的方法来反转nxm numpy数组并将前端零移位到后端

物理化学

假设

A = np.array([1,0,2,0,0,0,0],[1,2,0,3,5,0,0],[5,6,7,0,9,5,10]) 

从A我试图创建B这样:

B = np.array([2,0,1,0,0,0,0],[5,3,0,2,1,0,0],[10,5,9,0,7,6,5])

换句话说,B是A反转,前导零向后旋转。有矢量化的方法来完成此任务吗?

(创建B是为了让我可以向量化A中的整数值的总和,以及它们在对角线零偏角处的反射),例如A [1] [0] + A [1] [4],A [1] [1] + A [1] [3] =(B + A)[0:2]

我唯一想到的就是尝试这样的事情。

首先我扭转了

B = A.copy()
B = B[...,::-1]

哪个产量

B
Out[185]: 
array([[ 0,  0,  0,  0,  2,  0,  1],
       [ 0,  0,  5,  3,  0,  2,  1],
       [10,  5,  9,  0,  7,  6,  5]])

然后我用以下内容遍历每一行。

for i in range(0,B.shape[0]):
    a=np.trim_zeros(B[i])
    B[i]=np.pad(a,(0,B.shape[1]-a.shape[0])

B
Out[]: 
array([[ 2,  0,  1,  0,  0,  0,  0],
       [ 5,  3,  0,  2,  1,  0,  0],
       [10,  5,  9,  0,  7,  6,  5]])

但是实际数据集的行和列可能要大几个数量级。是否有针对此问题的矢量化解决方案。

迪卡卡

这是带有遮罩的矢量化的-

# nonzeros mask
nnz = A!=0

# Mask surrounded by nonzeros
max_accum = np.maximum.accumulate
island = max_accum(nnz,axis=1) & max_accum(nnz[:,::-1],axis=1)[:,::-1]

# Setup o/p array. Extract flipped A elements within each island per row and 
# assign into sorted mask i.e. brought to front mask places in o/p
out = np.zeros_like(A)
out[np.sort(island, axis=1)[:,::-1]] = A[:,::-1][island[:,::-1]]

说明

输入数组(供ref和另一种用于处理拐角情况并更好地解释):

In [147]: A
Out[147]: 
array([[ 1,  0,  2,  0,  0,  0,  0],
       [ 0,  0,  0,  2,  4,  0,  6],
       [ 5,  6,  7,  0,  9,  5, 10]])

非零包围的岛掩码:

前向累积面罩

In [148]: max_accum(nnz,axis=1)
Out[148]: 
array([[ True,  True,  True,  True,  True,  True,  True],
       [False, False, False,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])

向后累积的面罩,带有可翻转的nnz遮罩,执行向前累积,向后翻转

In [149]: max_accum(nnz[:,::-1],axis=1)[:,::-1]
Out[149]: 
array([[ True,  True,  True, False, False, False, False],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])

最终组合的面具给我们岛

In [150]: max_accum(nnz,axis=1) & max_accum(nnz[:,::-1],axis=1)[:,::-1]
Out[150]: 
array([[ True,  True,  True, False, False, False, False],
       [False, False, False,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])

选择和分配:

In [159]: A
Out[159]: 
array([[ 1,  0,  2,  0,  0,  0,  0],
       [ 0,  0,  0,  2,  4,  0,  6],
       [ 5,  6,  7,  0,  9,  5, 10]])

In [160]: island
Out[160]: 
array([[ True,  True,  True, False, False, False, False],
       [False, False, False,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])

In [161]: A[:,::-1]
Out[161]: 
array([[ 0,  0,  0,  0,  2,  0,  1],
       [ 6,  0,  4,  2,  0,  0,  0],
       [10,  5,  9,  0,  7,  6,  5]])

In [162]: island[:,::-1]
Out[162]: 
array([[False, False, False, False,  True,  True,  True],
       [ True,  True,  True,  True, False, False, False],
       [ True,  True,  True,  True,  True,  True,  True]])

因此,选择:

In [165]: A[:,::-1][island[:,::-1]]
Out[165]: array([ 2,  0,  1,  6,  0,  4,  2, 10,  5,  9,  0,  7,  6,  5])

要选择前面的遮罩,请对岛遮罩进行排序,该遮罩选择要分配给以下位置的o / p位置:

In [163]: np.sort(island, axis=1)[:,::-1]
Out[163]: 
array([[ True,  True,  True, False, False, False, False],
       [ True,  True,  True,  True, False, False, False],
       [ True,  True,  True,  True,  True,  True,  True]])

然后,将那些选定的A分配给带有排序的mask的输出:

In [166]: out
Out[166]: 
array([[ 2,  0,  1,  0,  0,  0,  0],
       [ 6,  0,  4,  2,  0,  0,  0],
       [10,  5,  9,  0,  7,  6,  5]])

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章