2014-10-16 119 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