2017-05-26 28 views

回答

3

一個量化的方法,利用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.]]) 
+0

這很好,但是我在理解它背後的邏輯時有點麻煩。 – bnicholl

+0

@bnicholl一步一步來。使用一個示例,運行每個步驟,查看輸出並按照那樣進行操作。使用我發佈的評論:'基本上這些步驟是:..'。這應該有所幫助。 – Divakar

+0

好的,我明白了。以前從未使用過像這樣的numpy bool數組。倒數第二行,就在退貨聲明將我拋棄之前。我無法理解0是如何被置於虛假指數中的。我想它只是如何numpy蒙面陣列的工作 – bnicholl

0

我不知道如何直接在numpy做到這一點。你可以通過利用Timsort穩定的優勢在Python循環中完成它,但它不會是速度顛簸。

import numpy as np 

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

zero = A.dtype.type() 

for row in A: 
    row[:] = sorted(row, key=zero.__lt__) 

# right-justified 
print(A) 

for row in A: 
    row[:] = sorted(row, key=zero.__lt__, reverse=True) 

# left-justified 
print(A) 
0
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.]] 
0

隨着每行包含至少一個零的假設,並沒有否定,這只是一個分區:

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

編輯:這慢騰騰行,所以是好一點比這更好

+0

不知道這個真的,例如假設一行是:[[0.,6.,3.,2.]',它給出:[[0.,2.,3.,6。],'。 – Divakar

+1

Docs說:'兩個分區中元素的排序是未定義的。所以,你必須另外使用'argsort',然後進行高級索引以保持順序。 – Divakar

+0

的確如此 - 只有在訂單無關緊要時纔有用。我做了一個編輯 – Eric

相關問題