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