获取索引映射的数组的子数组的有效方法

Cup*_*tor 4 python arrays numpy matrix

我有一个矩阵说a.我需要得到它的一个子矩阵,基本上它的索引来自主矩阵索引的映射(这个映射不一定是1-1).我有以下代码来生成子矩阵,这里映射被认为是sum.

import numpy as np
def transform(A):
    B=np.zeros(A.flatten().shape[0])
    for i in range(A.flatten().shape[0]):
        multi_idx=np.unravel_index(i,A.shape)
        B[np.sum(multi_idx)]=A[multi_idx] #the mapping applied on the indices: B[np.sum(multi_idx)]
    return B       
A=np.arange(27).reshape([3,3,3])
print A
print transform(A)        
Run Code Online (Sandbox Code Playgroud)

随着输出:

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

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]]
[  0.   9.  18.  21.  24.  25.  26.   0.   0.   0.   0.   0.   0.   0.   0.
   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 6

np.ogrid可以是基于数组中的索引创建表达式的便捷方式.例如,

import numpy as np

A = np.arange(27).reshape([3,3,3])
B = np.zeros(A.size)
i, j, k = np.ogrid[0:3, 0:3, 0:3]
B[i+j+k] = A
print(B)
Run Code Online (Sandbox Code Playgroud)

产量

[  0.   9.  18.  21.  24.  25.  26.   0.   0.   0.   0.   0.   0.   0.   0.
   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.   0.]
Run Code Online (Sandbox Code Playgroud)

注意分配

B[X] = A
Run Code Online (Sandbox Code Playgroud)

相当于

B[X.ravel()] = A.ravel()
Run Code Online (Sandbox Code Playgroud)

并且从左到右按顺序完成分配.因此,如果X有许多重复值,则只有最后一个值最终会影响B.这具有以您希望的方式处理地图的非一对一的效果.

  • 对于那些想知道的人,[这是gh-3798](https://github.com/numpy/numpy/pull/3798). (3认同)