2014-10-16 165 views
1

我有兩個數組。在numpy中用3d數組索引一個二維數組

「a」,一個2d numpy數組。

import numpy.random as npr 

a = array([[5,6,7,8,9],[10,11,12,14,15]]) 
array([[ 5, 6, 7, 8, 9], 
     [10, 11, 12, 14, 15]]) 

「idx」,一個三維numpy數組,構成三個索引變體,我想用索引「a」。

idx = npr.randint(5, size=(nsamp,shape(a)[0], shape(a)[1])) 
array([[[1, 2, 1, 3, 4], 
     [2, 0, 2, 0, 1]], 

     [[0, 0, 3, 2, 0], 
     [1, 3, 2, 0, 3]], 

     [[2, 1, 0, 1, 4], 
     [1, 1, 0, 1, 0]]]) 

現在我想指數「」三用「IDX」索引次如下獲取對象:

array([[[6, 7, 6, 8, 9], 
     [12, 10, 12, 10, 11]], 

     [[5, 5, 8, 7, 5], 
     [11, 14, 12, 10, 14]], 

     [[7, 6, 5, 6, 9], 
     [11, 11, 10, 11, 10]]]) 

天真「一[IDX]」不工作。任何想法如何做到這一點? (我使用Python 3.4和NumPy的1.9)

+0

切切實實的這個已經解釋了很多次。你必須告訴索引到第二維,所以它會像'a [indx,[[[0],[1]]]]'... – seberg 2014-10-17 08:53:58

回答

3

您可以使用choose,使從a選擇:

>>> np.choose(idx, a.T[:,:,np.newaxis]) 
array([[[ 6, 7, 6, 8, 9], 
     [12, 10, 12, 10, 11]], 

     [[ 5, 5, 8, 7, 5], 
     [11, 14, 12, 10, 14]], 

     [[ 7, 6, 5, 6, 9], 
     [11, 11, 10, 11, 10]]]) 

正如你所看到的, a必須從形狀爲(2, 5)的陣列重塑爲首先形狀爲(5, 2, 1)的陣列。這基本上是這樣的,它可以用idx進行廣播,其形狀爲(3, 2, 5)

(我學會了從這裏@ immerrr的回答這個方法:https://stackoverflow.com/a/26225395/3923281

+0

謝謝!偉大的作品 – roschu 2014-10-16 14:06:14

+1

作爲「選擇」這一事實的一個證明,這個事實很棘手,我花了一段時間才知道發生了什麼事情。說到廣播,我不認爲'(5,2,1)'可以用' (3,2,5)'。它的工作原理是,「選擇」使用索引器中的值「剝離」第一個軸。因此,給定'x = aT [:,:,np.newaxis]','idx'必須可以用'x [0]'來廣播,這是因爲'x [0] .shape ==(2,1 )'。 – immerrr 2014-10-17 12:23:59

+1

謝謝@immerrr - 再看一遍,我同意我對「choose」的解釋有點不準確。在接下來的幾天我有機會時,我會磨合它。 – 2014-10-17 15:43:45

0

您可以使用take陣列方法:

import numpy 

a = numpy.array([[5,6,7,8,9],[10,11,12,14,15]]) 

idx = numpy.random.randint(5, size=(3, a.shape[0], a.shape[1])) 

print a.take(idx) 
+0

謝謝你的幫助! – roschu 2014-10-16 14:46:47

+3

'take'失去'a'的結構。如果idx全爲零,'take'將產生一個滿'5'的數組,而它應該是[[5 ...],[10 ...],[5 ...],[10 ... ],[5 ...],[10 ...]]' – immerrr 2014-10-17 19:41:58