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

时间:2017-05-26 21:44:28

标签: python numpy

如果我有一个如下所示的numpy数组,我怎样才能正确对齐或左对齐元素tat大于零

[[ 0.  5.  0.  2.]
 [ 0.  0.  3.  2.]
 [ 0.  0.  0.  0.]
 [ 2.  0.  0.  1.]]
例如,如果我想右对齐这个数组,它看起来像:

[[ 5.  2.  0.  0.]
 [ 3.  2.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 2.  1.  0.  0.]]

3 个答案:

答案 0 :(得分:4)

一种利用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

基本上步骤是:

  • 制作一个大于零的面具。

  • 获取左对齐或右对齐蒙版,其中大于元素将放置在零初始化数组中。为了获得这样一个合理的掩码,我们只需沿着每一行对步骤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.]])

答案 1 :(得分:0)

假设每行至少包含一个零,没有负数,这只是一个分区:

>>> np.partition(x, 1)
array([[ 0.,  0.,  5.,  2.],
       [ 0.,  0.,  3.,  2.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  2.,  1.]])

编辑:这会对行进行混洗,因此比排序

更好

答案 2 :(得分:-1)

import numpy as np

array = [ 
          [ 0.,  5.,  0.,  2.],
          [ 0.,  0.,  3.,  2.],
          [ 0.,  0.,  0.,  0.],
          [ 2.,  0.,  0.,  1.]
        ]


def move(array, right = True):
  temp = []
  for x in array:
    x = np.array(x)
    #check positive arrays
    if len(np.where(x == 0)[0]) != len(x):
      if right:
        # little faster, compare to [::-1]
        # nonzero on right
        temp.append(x[np.argsort(-x)])
      else:
        # nonzero on left
        temp.append(np.sort(x))
    else:
        # no interchange needed
        temp.append(x)
  return temp

print (move(array, 1))

[array([ 5.,  2.,  0.,  0.]), array([ 3.,  2.,  0.,  0.]), array([ 0.,  0.,  0.,  0.]), array([ 2.,  1.,  0.,  0.])]

print (move(array, 0))

[array([ 0.,  0.,  2.,  5.]), array([ 0.,  0.,  2.,  3.]), array([ 0.,  0.,  0.,  0.]), array([ 0.,  0.,  1.,  2.])]

print (np.concatenate(list(zip(move(array, 1))), axis=0))

[[ 5.  2.  0.  0.]
 [ 3.  2.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 2.  1.  0.  0.]]