2014-10-07 78 views
2

有一些問題很接近,但我還沒有找到具體的答案。我正在嘗試對給定座標軸上的numpy 3D數組進行一些就地排序。我不想簡單的排序,但我想根據我自己的索引來求解這個數組。例如根據給定索引進行就地numpy數組排序

a = np.random.rand((3,3,3)) 

,讓說,我想根據舊陣列的以下指標訴諸的最後一個維度:

new_order = [1,2,0] 

我會希望能夠說:

a[:,:,new_order] = a 

但這並不像預期的那樣。建議?

+2

你在找'a = a [:,:,new_order]'嗎? – farenorth 2014-10-07 15:47:04

+0

這已經很久了,我忘了你可以在Matlab中做到這一點。 – farenorth 2014-10-07 17:00:21

回答

4

np.ndarray.sort是自稱是唯一的一種,它並沒有給你太多的控制。

將訂單索引放在正確的工作 - 但可以給不可預知的結果。很明顯,它正在進行某種順序分配,而左側的較早分配會影響右側的值。

In [719]: a=np.arange(12).reshape(3,4) 
In [720]: a[:,[0,1,3,2]]=a 
In [721]: a 
Out[721]: 
array([[ 0, 1, 2, 2], 
     [ 4, 5, 6, 6], 
     [ 8, 9, 10, 10]]) 

要做到這種分配可以預見需要某種緩衝。

In [728]: a[:,[0,1,3,2]]=a.copy() 
In [729]: a 
Out[729]: 
array([[ 0, 1, 3, 2], 
     [ 4, 5, 7, 6], 
     [ 8, 9, 11, 10]]) 

索引的權利繞過這個,但這不是就地。變量a指向一個新的對象。

In [731]: a=a[:,[0,1,3,2]] 
In [732]: a 
Out[732]: 
array([[ 0, 1, 3, 2], 
     [ 4, 5, 7, 6], 
     [ 8, 9, 11, 10]]) 

然而,隨着[:]分配可以解決這個問題:

In [738]: a=np.arange(12).reshape(3,4) 
In [739]: a.__array_interface__ 
Out[739]: 
{'data': (181868592, False), # 181... is the id of the data buffer 
'descr': [('', '<i4')], 
'shape': (3, 4), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [740]: a[:]=a[:,[0,1,3,2]] 
In [741]: a.__array_interface__ 
Out[741]: 
{'data': (181868592, False), # same data buffer 
'descr': [('', '<i4')], 
'shape': (3, 4), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [742]: a 
Out[742]: 
array([[ 0, 1, 3, 2], 
     [ 4, 5, 7, 6], 
     [ 8, 9, 11, 10]]) 

的事實a.data ID是一樣的表示這是就地行動。但是用其他索引來測試它是很好的,以確保它能做到你想要的。

但是,'就地'排序是必要的嗎?如果數組非常大,則可能需要避免內存錯誤。但是我們不得不測試替代方案以查看它們是否有效。

inplace也很重要,如果有一些其他變量使用相同的數據。例如

b = a.T # a transpose 

隨着a[:]=b的行將被重新排序。 ab繼續共享相同的data。用a=,b不變。現在將ab分離。

相關問題