LC117
LC117

Reputation: 786

Get values from an array given a list of coordinates/locations with Numpy

I have a first 3D numpy array and a second numpy array containing the locations (coordinates) of elements of the first I am interested in.

first = np.array([[[100, 101, 102],
                  [103, 104, 105],
                  [106, 107, 108]],

                 [[109, 110, 111],
                  [112, 113, 114],
                  [115, 116, 117]],

                 [[118, 119, 120],
                  [121, 122, 123],
                  [124, 125, 126]]])


second = np.array([[0, 1, 0],
                   [1, 1, 0],
                   [1, 0, 0],
                   [0, 0, 0],

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

result = np.array([103, 112, 109, 100, 104, 113, 110, 101])

The result I would like: all values located at the positions contained in the second array.

Using first[second] does not do the trick. I would like to avoid looping.

Upvotes: 2

Views: 1869

Answers (1)

Mark
Mark

Reputation: 92440

You can create a flat index array from your second array with numpy.ravel_multi_index(). This can then be passed to take() which will give you a flat list of values.

Given a starting array:

import numpy as np
m = np.arange(100, 127).reshape([3, 3, 3])

of

[[[100 101 102]
  [103 104 105]
  [106 107 108]]

 [[109 110 111]
  [112 113 114]
  [115 116 117]]

 [[118 119 120]
  [121 122 123]
  [124 125 126]]]

and your indexes:

second = np.array(
    [[0, 1, 0],
     [1, 1, 0],
     [1, 0, 0],
     [0, 0, 0],

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

i = np.ravel_multi_index(second.T, m.shape)
m.take(i)

results in:

array([103, 112, 109, 100, 104, 113, 110, 101])

Upvotes: 4

Related Questions