Cupitor
Cupitor

Reputation: 11657

Efficient way of getting a subarray of an array that the indices are mapped

I have a matrix say a. I need to get a sub-matrix of it, which basically the indices of it are coming from a mapping on the indices of the main matrix(This map is not necessarily 1-1). I have the following code to generate the sub-matrix and here the mapping is considered to be 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)        

With output:

[[[ 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.]

Upvotes: 4

Views: 181

Answers (1)

unutbu
unutbu

Reputation: 880499

np.ogrid can be a convenient way to make expressions based on the indices in an array. For example,

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)

yields

[  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.]

Note that the assignment

B[X] = A

is equivalent to

B[X.ravel()] = A.ravel()

and the assignment is done in order from left to right. Thus, if X has many duplicate values, only the last value ultimately affects B. This has the effect of handling the non-one-to-one-ness of your map in the way you desire.

Upvotes: 6

Related Questions