2015-12-07 91 views
4

据我所知,通过Sort N-D numpy array by another 1-D array使用花哨的索引,我可以做列如下c = a[:, :, b]b定义为,我想通过列排序排序ND numpy的阵列与一个较小的ND阵列

>>> a = np.array([[[ 0, 1], [ 2, 3]], 
        [[ 4, 5], [ 6, 7]], 
        [[ 8, 9], [10, 11]]]) 
>>> b = np.array([1, 0]) 
>>> c = a[:, :, b] 
>>> c 
array([[[ 1, 0], 
     [ 3, 2]], 

     [[ 5, 4], 
     [ 7, 6]], 

     [[ 9, 8], 
     [11, 10]]]) 

现在我增加b有2个输入b2相当于我多么想每组2×2的排列在a

>>> b2 = np.array([[1, 0], [0, 1], [1, 0]]) 
>>> c2 = ? 
>>> c2 
array([[[ 1, 0], 
     [ 3, 2]], 

     [[ 4, 5], 
     [ 6, 7]], 

     [[ 9, 8], 
     [11, 10]]]) 

我有更大的一组输入和我有一个函数返回一个类似于'b2'的数组,它向我提供了我应该获取的信息。因此,我可以知道我应该填入c2 = ?以获得期望的结果吗?

+0

对于那个期望的输出,'b2'不应该是'np.array([[1,0],[0,1],[1,0]])'(最后一行交换)吗? –

+0

@ajcr感谢您发现错误! :) – kent

回答

5

下面是与看中索引的一种方法 -

(a[np.arange(a.shape[0])[:,None],:,b2]).transpose(0,2,1) 

样品运行 -

In [191]: a 
Out[191]: 
array([[[7, 8, 5, 2, 0], 
     [6, 7, 0, 7, 1], 
     [7, 6, 5, 4, 0]], 

     [[8, 0, 5, 5, 7], 
     [4, 3, 4, 0, 1], 
     [8, 6, 3, 2, 4]], 

     [[3, 2, 7, 3, 7], 
     [4, 3, 0, 1, 5], 
     [4, 3, 7, 8, 7]]]) 

In [192]: b2 
Out[192]: 
array([[1, 2, 4, 3, 0], 
     [4, 2, 0, 1, 3], 
     [1, 3, 4, 0, 2]]) 

In [193]: (a[np.arange(a.shape[0])[:,None],:,b2]).transpose(0,2,1) 
Out[193]: 
array([[[8, 5, 0, 2, 7], 
     [7, 0, 1, 7, 6], 
     [6, 5, 0, 4, 7]], 

     [[7, 5, 8, 0, 5], 
     [1, 4, 4, 3, 0], 
     [4, 3, 8, 6, 2]], 

     [[2, 3, 7, 3, 7], 
     [3, 1, 5, 4, 0], 
     [3, 8, 7, 4, 7]]]) 
+1

这是[混合高级和基本索引]的好例子(http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#combining-advanced-and-basic-indexing)。 – unutbu

+0

@unutbu我甚至都不知道我在搞混了! :) – Divakar

+0

感谢您的答案!这真的很好,我学到了很多东西。 – kent

1

如果没人发现纯花式索引的解决方案,这在这里是一个通过第一轴环:

np.asarray([a[n,:,p] for n,p in enumerate(b2)]) 

array([[[ 1, 3], 
    [ 0, 2]], 

    [[ 4, 6], 
    [ 5, 7]], 

    [[ 9, 11], 
    [ 8, 10]]]) 
+0

感谢您的回答!花哨索引解决方案将更好bcos速度是我正在寻找的。 :) – kent

1

与类似的东西解决方案,但没有transpose

In [259]: I,J, K = np.ogrid[:3,:2,:2] 

In [260]: a[I, J, b[:,None,:]] 
Out[260]: 
array([[[ 1, 0], 
     [ 3, 2]], 

     [[ 4, 5], 
     [ 6, 7]], 

     [[ 9, 8], 
     [11, 10]]]) 

我使用ogrid(或np.ix_)作为产生2个三维阵列与b[:,None,:]广播以产生一组的(3,2,2)索引的紧凑的方式。

等效满Nones是:

a[np.arange(3)[:,None,None], np.arange(2)[None,:,None], b[:,None,:]] 

(这使得它更清晰的是b是选择沿第一和最后一个轴项目)

要查看完整的广播的索引数组,打印:

np.broadcast_arrays(I,J,b[:,None,:]) 
+0

谢谢!与Divakar的回答相似,我学到了很多东西,也感谢他们一步一步地解释它。 – kent