2013-06-12 82 views
3

我希望有人能向我解釋以下行爲我與numpy的陣列觀察:與numpy的陣列質樸的行爲

>>> import numpy as np 
>>> data_block=np.zeros((26,480,1000)) 
>>> indices=np.arange(1000) 
>>> indices.shape 
(1000,) 
>>> data_block[0,:,:].shape 
(480, 1000)   #fine and dandy 
>>> data_block[0,:,indices].shape 
(1000, 480)   #what happened???? why the transpose???? 
>>> ind_slice=np.arange(300) # this is more what I really want. 
>>> data_block[0,:,ind_slice].shape 
(300, 480)  # transpose again! arghhh! 

我不明白這一點變調行爲,這是我想要的東西非常不方便做。任何人都可以向我解釋嗎?獲得data_block的子集的另一種方法將是一個很大的好處。

+0

實際的規則很簡單。如果花哨的指數(和標量也是這方面的幻想,這可能很奇怪,但是......)都是*連續的* numpy可以猜測你想從哪裏得到花式指數產生的維度。如果他們不是連續的,那就把他們放在首位。如果你記得所有花哨的索引都是「一體」的,這是有道理的。 – seberg

回答

3

你可以達到你想要的結果是這樣的:

>>> data_block[0,:,:][:,ind_slice].shape 
(480L, 300L) 

我承認我沒有多麼複雜numpy的索引原理的完整理解,但似乎the documentation在您遇到的麻煩提示:

基本切片與多於一個的非:在切片元組條目,動作使用單個非切片的像反覆應用:條目,其中所述非:條目依次拍攝(與所有其它非:條目由:)代替。因此,在基本切片下,x[ind1,...,ind2,:]的行爲如同x[ind1][...,ind2,:]

警告:以上是不適用於高級切片。

和。 。 。

高級索引被觸發時選擇對象obj是非元組序列對象,ndarray(數據類型整數或布爾的),或具有至少一個序列對象或ndarray(的數據元組類型整數或布爾)。

因此,您通過使用ind_slice數組而不是常規切片索引來觸發該行爲。

文檔本身說這種索引「可能有點令人難以理解」,所以我們都遇到這個問題並不令人驚訝:-)。

1

一旦你瞭解瞭如何花哨的索引工作,真的沒什麼值得驚訝的。如果您將列表或數組作爲索引,則它們必須全部具有相同的形狀,或者可以以通用形狀進行廣播。該形狀將成爲返回數組的基本形狀。如果有索引是切片,那麼基礎形狀數組中的每個條目都將是多維的,因此基礎形狀會獲得額外條目的擴展。雖然這看起來可能是一個奇怪的選擇,但它確實是唯一符合多維花式索引的選擇。作爲一個例子,揣摩你會期望回報形狀,如果你做了以下內容:

>>> ind_slice=np.arange(16).reshape(4, 4) 
>>> data_block[ind_slice, :, ind_slice].shape 
(4, 4, 480) # No, (4, 4, 480, 4, 4) is not a better option 

有幾種方法,讓你所追求的。對於你的問題的具體情況,最明顯的是不使用花哨的索引,你可以讓你用切片問:

>>> data_block[0, :, :300].shape 
(480, 300) 

如果你確實需要花哨的索引,你可以替換broadcastable陣列片:

>>> data_block[0, np.arange(480)[:, None], ind_slice].shape 
(480, 300) 

你可能想,如果你需要使用數組來代替更爲複雜的片來看看np.ogridnp.mgrid

+0

謝謝你勇敢的解釋它,海梅。我仍然覺得很困惑。謝謝。 –