[英]How does numpy order array slice indices?
我有一個形狀的np.array data
(28,8,20),我只需要它的某些條目,所以我正在切片:
In [41]: index = np.array([ 5, 6, 7, 8, 9, 10, 11, 17, 18, 19])
In [42]: extract = data[:,:,index]
In [43]: extract.shape
Out[43]: (28, 8, 10)
到目前為止一切都那么好,一切都應該如此。 但是現在我只想看看第一行最后一個索引的前兩個條目:
In [45]: extract[0,:,np.array([0,1])].shape
Out[45]: (2, 8)
等等,應該是(8,2)。 它改變了指數,即使我最后一次切片時沒有! 根據我的理解,以下應采取相同的行動:
In [46]: extract[0,:,:2].shape
Out[46]: (8, 2)
......但它給了我我想要的東西! 但是,只要我有一個3D數組,這兩種方法似乎都是等價的:
In [47]: extract[:,:,np.array([0,1])].shape
Out[47]: (28, 8, 2)
In [48]: extract[:,:,:2].shape
Out[48]: (28, 8, 2)
那么,如果我不僅需要前兩個條目而且需要不規則列表,我該怎么辦? 我當然可以在操作后轉置矩陣,但這看起來非常違反直覺。 我的問題的一個更好的解決方案是這個(雖然可能有一個更優雅的):
In [64]: extract[0][:,[0,1]].shape
Out[64]: (8, 2)
這把我們帶到了實際
我想知道這種行為的原因是什么? 無論誰決定它應該如何工作,可能比我更了解編程,並認為這在某些方面是一致的,我完全沒有。 除非我有辦法理解它,否則我可能會繼續關注這個問題。
這是(高級)部分索引的情況。 有2個索引數組和1個切片
如果索引子空間是分開的(通過切片對象),則首先是廣播的索引空間,然后是x的切片子空間。
http://docs.scipy.org/doc/numpy-1.8.1/reference/arrays.indexing.html#advanced-indexing
高級索引示例注意到,當ind_1
, ind_2
廣播子空間的shape (2,3,4)
表示:
但是,x [:,ind_1,:,ind_2]具有形狀(2,3,4,10,30,50),因為在索引子空間中沒有明確的位置,因此它被添加到開頭。 始終可以使用.transpose()在任何需要的位置移動子空間。
換句話說,這個索引與x[:, ind_1][[:,ind_2]
。 2個陣列共同操作以定義(2,3,4)
子空間。
在你的例子中, extract[0,:,np.array([0,1])]
被理解為意味着,選擇一個(2,)
子空間([0]和[0,1]共同行動,而不是順序) ,並以某種方式將其與中間維度相結合。
一個更精細的例子是extract[[1,0],:,[[0,1],[1,0]]]
,它產生一個(2,2,8)
數組。 這是第一維和最后一維的(2,2)
子空間,加上中間維。 另一方面, X[[1,0]][:,:,[[0,1],[1,0]]]
產生一個(2,8,2,2)
,從第一個和最后一個選擇尺寸分開。
關鍵的區別在於索引選擇是順序操作還是聯合操作。 [...] [...]語法已經可以按順序運行。 高級索引為您提供了一種聯合索引方式。
你是對的,這很奇怪。 我只能冒這個猜測。 我認為這與a[[0,1],[0,1],[0,1]].shape
是(2,)
而不是(2,2,2)
並且a[0,1,[0,1,2]]
實際上意味着a[[0,0,0],[1,1,1],[0,1,2]]
計算為array([a[0,1,0],a[0,1,1],a[0,1,2]])
。 也就是說,您逐步瀏覽每個維度的列表 - 索引,長度 - 一個列表和標量被廣播以匹配最長的。
從概念上講,這會使你的extract[0,:,[0,1]]
等同於extract[[0,0],[slice(None),slice(None)],[0,1]]
(該語法不是但是,如果您手動指定它,則不會被接受。 單步執行索引后,將評估為array([extract[0,slice(None),0],extract[0,slice(None),1])
。 每個內部提取都評估為一個形狀(8,)
數組,因此完整的結果是形狀(2,8)
。
總而言之,我認為廣播的副作用是使所有維度都具有相同長度的索引列表,這導致:
廣播也是如此。 這是我的假設,但我沒有看到numpy
如何做到這一點的內部運作。 也許專家會提出更好的解釋。
這個假設並不能解釋為什么extract[:,:,[0,1]]
不會導致相同的行為。 我不得不假設只有前導“:”的情況是特殊的,以避免參與列表索引邏輯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.