繁体   English   中英

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

[英]Python: moving all elements greater than 0 to left and right in numpy array

如果我有一个如下所示的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.]]

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

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

>>> np.partition(x, 1)
array([[ 0.,  0.,  5.,  2.],
       [ 0.,  0.,  3.,  2.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  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.]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM