Python:在numpy数组中将所有大于0的元素左右移动

bni*_*oll 5 python numpy

如果我有一个如下的numpy数组,我该如何右对齐或左对齐tat元素大于零

[[ 0.  5.  0.  2.]
 [ 0.  0.  3.  2.]
 [ 0.  0.  0.  0.]
 [ 2.  0.  0.  1.]]
Run Code Online (Sandbox Code Playgroud)

例如,如果我想对这个数组进行对正,则它看起来像:

[[ 5.  2.  0.  0.]
 [ 3.  2.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 2.  1.  0.  0.]]
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 5

一种矢量化方法利用masks-

def justify_rows(a, side='left'):
    mask = a>0
    justified_mask = np.sort(mask,1)
    if side=='left':
        justified_mask = justified_mask[:,::-1]
    out = np.zeros_like(a) 
    out[justified_mask] = a[mask]
    return out
Run Code Online (Sandbox Code Playgroud)

基本上步骤是:

  • 制作一个大于零的掩码。

  • 获取左对齐或右对齐掩码,其中大于元素将放置在零初始化数组中。为了得到这样一个合理的掩码,我们简单地沿着每一行对 step-1 的掩码进行排序,这会将每行中的掩码扔到True右边。因此,另外我们需要为左对齐的情况翻转每一行。

  • 最后,使用对齐的掩码分配给输出数组,并使用步骤 1 中的掩码从输入数组中进行选择。

样品运行 -

In [105]: a
Out[105]: 
array([[ 0.,  5.,  0.,  2.],
       [ 0.,  0.,  3.,  2.],
       [ 0.,  0.,  0.,  0.],
       [ 2.,  0.,  0.,  1.]])

In [106]: justify_rows(a, side='left')
Out[106]: 
array([[ 5.,  2.,  0.,  0.],
       [ 3.,  2.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 2.,  1.,  0.,  0.]])

In [107]: justify_rows(a, side='right')
Out[107]: 
array([[ 0.,  0.,  5.,  2.],
       [ 0.,  0.,  3.,  2.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  2.,  1.]])
Run Code Online (Sandbox Code Playgroud)