Home > front end >  How to use the value of a 2d array as an index to a 3d array in numpy?
How to use the value of a 2d array as an index to a 3d array in numpy?

Time:04-10

I have a 2d array, A, with shape (n x m), where each element of the array at position (i,j) holds a third value k. I want to increment a 3d array with dimensions nxmxl at position (k,i,j) based on the 2d array value and position.

So for example if

A = [[0,1],[3,3]] -> I would want B to be 

[[[1,0],
  [0,0]],

  [0,1],
  [0,0]],

  [0,0],
  [0,1]],

  [0,0],
  [0,2]]]

How do you do this in numpy efficiently?

CodePudding user response:

I can produce your B with:

In [208]: res = np.zeros((4,2,2),int)
In [209]: res.reshape(4,4)[np.arange(4), A.ravel()] = [1,1,1,2]
In [210]: res
Out[210]: 
array([[[1, 0],
        [0, 0]],

       [[0, 1],
        [0, 0]],

       [[0, 0],
        [0, 1]],

       [[0, 0],
        [0, 2]]])

I use the reshape because A values look more like indices of

In [211]: res.reshape(4,4)
Out[211]: 
array([[1, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 1],
       [0, 0, 0, 2]])

CodePudding user response:

The question is somewhat ambiguous, but if the intent is to increment some unknown array B at indices (0,0,0), (1,0,1), (3,1,0), and (3,1,1), then the following should be fine:

B[(A.ravel(), )   np.unravel_index(np.arange(np.prod(A.shape)), A.shape)]  = increment

For example:

A = np.array([[0,1],[3,3]])
B = np.zeros((4,2,2), dtype=int)
increment = 1

B[(A.ravel(), )   np.unravel_index(np.arange(np.prod(A.shape)), A.shape)]  = increment

>>> B
array([[[1, 0],
        [0, 0]],

       [[0, 1],
        [0, 0]],

       [[0, 0],
        [0, 0]],

       [[0, 0],
        [1, 1]]])

Another way of doing the same thing is:

w, h = A.shape
indices = (A.ravel(),)   tuple(np.mgrid[:w, :h].reshape(2, -1))

# then
B[indices]  = increment
  • Related