You can use np.take_along_axis to do that:

import numpy as np
np.random.seed(0)
a = np.random.randint(100, size=(66, 5))
b = np.random.random(size=(100, 66, 5))
c = np.take_along_axis(b, a[np.newaxis], axis=0)[0]
# Test some element
print(c[25, 3] == b[a[25, 3], 25, 3])
# True
Answer from javidcf on Stack Overflow
๐ŸŒ
Python Like You Mean It
pythonlikeyoumeanit.com โ€บ Module3_IntroducingNumpy โ€บ AccessingDataAlongMultipleDimensions.html
Accessing Data Along Multiple Dimensions in an Array โ€” Python Like You Mean It
NumPy specifies the row-axis (students) ... each axis (dimension), to uniquely specify an element in this 2D array; the first number specifies an index along axis-0, the second specifies an index along axis-1....
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ numpy-index-3d-array-with-index-of-last-axis-stored-in-2d-array
Numpy: Index 3D array with index of last axis stored in 2D array - GeeksforGeeks
July 23, 2025 - Step 2: We use np.expand_dims to add an extra dimension to z_indices, making its shape (3, 3, 1). This is necessary because take_along_axis requires the indices array to have the same number of dimensions as the array being indexed. Step 3: We use np.take_along_axis to select elements from val_arr along the z-axis (axis=0) using the indices from z_indices_expanded. Step 4: We use np.squeeze to remove the extra dimension added by expand_dims, resulting in the final 2D array result_arr. ... import numpy as np # Create a 3D array of shape (3, 3, 3) val_arr = np.arange(27).reshape(3, 3, 3) # Create a 2D array of indices of shape (3, 3) z_indices = np.array([[1, 0, 2], [0, 0, 1], [2, 0, 1]])
Top answer
1 of 4
16

You can use choose to make the selection:

>>> z_indices.choose(val_arr)
array([[ 9,  1, 20],
       [ 3,  4, 14],
       [24,  7, 17]])

The function choose is incredibly useful, but can be somewhat tricky to make sense of. Essentially, given an array (val_arr) we can make a series of choices (z_indices) from each n-dimensional slice along the first axis.

Also: any fancy indexing operation will create a new array rather than a view of the original data. It is not possible to index val_arr with z_indices without creating a brand new array.

2 of 4
7

With readability, np.choose definitely looks great.

If performance is of essence, you can calculate the linear indices and then use np.take or use a flattened version with .ravel() and extract those specific elements from val_arr. The implementation would look something like this -

def linidx_take(val_arr,z_indices):

    # Get number of columns and rows in values array
     _,nC,nR = val_arr.shape

     # Get linear indices and thus extract elements with np.take
    idx = nC*nR*z_indices + nR*np.arange(nR)[:,None] + np.arange(nC)
    return np.take(val_arr,idx) # Or val_arr.ravel()[idx]

Runtime tests and verify results -

Ogrid based solution from here is made into a generic version for these tests, like so :

In [182]: def ogrid_based(val_arr,z_indices):
     ...:   v_shp = val_arr.shape
     ...:   y,x = np.ogrid[0:v_shp[1], 0:v_shp[2]]
     ...:   return val_arr[z_indices, y, x]
     ...: 

Case #1: Smaller datasize

In [183]: val_arr = np.random.rand(30,30,30)
     ...: z_indices = np.random.randint(0,30,(30,30))
     ...: 

In [184]: np.allclose(z_indices.choose(val_arr),ogrid_based(val_arr,z_indices))
Out[184]: True

In [185]: np.allclose(z_indices.choose(val_arr),linidx_take(val_arr,z_indices))
Out[185]: True

In [187]: %timeit z_indices.choose(val_arr)
1000 loops, best of 3: 230 ยตs per loop

In [188]: %timeit ogrid_based(val_arr,z_indices)
10000 loops, best of 3: 54.1 ยตs per loop

In [189]: %timeit linidx_take(val_arr,z_indices)
10000 loops, best of 3: 30.3 ยตs per loop

Case #2: Bigger datasize

In [191]: val_arr = np.random.rand(300,300,300)
     ...: z_indices = np.random.randint(0,300,(300,300))
     ...: 

In [192]: z_indices.choose(val_arr) # Seems like there is some limitation here with bigger arrays.
Traceback (most recent call last):

  File "<ipython-input-192-10c3bb600361>", line 1, in <module>
    z_indices.choose(val_arr)

ValueError: Need between 2 and (32) array objects (inclusive).


In [194]: np.allclose(linidx_take(val_arr,z_indices),ogrid_based(val_arr,z_indices))
Out[194]: True

In [195]: %timeit ogrid_based(val_arr,z_indices)
100 loops, best of 3: 3.67 ms per loop

In [196]: %timeit linidx_take(val_arr,z_indices)
100 loops, best of 3: 2.04 ms per loop
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ indexing-multi-dimensional-arrays-in-python-using-numpy
Indexing Multi-dimensional arrays in Python using NumPy | GeeksforGeeks
April 28, 2025 - ... To index a multi-dimensional array you can index with a slicing operation similar to a single dimension array. ... import numpy as np arr_m = np.arange(12).reshape(2, 2, 3) # Indexing print(arr_m[0:3]) print() print(arr_m[1:5:2,::3])
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 55054603 โ€บ index-a-3d-array-with-2d-array-numpy
python - Index a 3D array with 2D array numpy - Stack Overflow
Therefore to generate the result array from the source array, we need several n-tuples, one n-tuple for each element-position of the final result array. For each element-position of the result array, the n-tuple of indices will be constructed ...
๐ŸŒ
Regenerativetoday
regenerativetoday.com โ€บ indexing-and-slicing-of-1d-2d-and-3d-arrays-using-numpy
Indexing and Slicing of 1D, 2D and 3D Arrays Using Numpy โ€“ Regenerative
So, we can select those as before with x[1:]. All the elements are in first and second rows of both the two-dimensional array. Row index should be represented as 0:2. Column index is 1:4 as the elements are in first, second and third column. Combining all together: ... I hope this helps. Please try with different numbers and slices to learn more. #numpy #numpyarray #python #dataanalysis #datascience #dataanalytics
Find elsewhere
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ numpy โ€บ numpy_array_indexing.asp
NumPy Array Indexing
Think of 2-D arrays like a table with rows and columns, where the dimension represents the row and the index represents the column. Access the element on the first row, second column: import numpy as np arr = np.array([[1,2,3,4,5], [6,7,8,9,10]]) ...
๐ŸŒ
Towards Data Science
towardsdatascience.com โ€บ home โ€บ latest โ€บ introducing numpy, part 2: indexing arrays
Introducing NumPy, Part 2: Indexing Arrays | Towards Data Science
January 13, 2025 - Let's start by looking at a 3D array with a shape of (2, 3, 4). You can think of the first value in the shape tuple as the number of 2D arrays within that 3D array. The next two numbers are treated as the shape tuple for these 2D arrays, ...
๐ŸŒ
NumPy
numpy.org โ€บ devdocs โ€บ user โ€บ basics.indexing.html
Indexing on ndarrays โ€” NumPy v2.6.dev0 Manual
The simplest case of indexing with N integers returns an array scalar representing the corresponding item. As in Python, all indices are zero-based: for the i-th index \(n_i\), the valid range is \(0 \le n_i < d_i\) where \(d_i\) is the i-th element of the shape of the array.
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 56152860 โ€บ numpy-3d-array-indexing-works-for-2d-how-to-do-for-3d
python - Numpy 3D array Indexing : Works for 2D, how to do for 3D? - Stack Overflow
May 15, 2019 - But now I want to do it for a 3D output array, where key_idx2D is a 2D array with the first dimension representing table_id. Please refer to the figure below: ... key_idx2D = np.array([[1, 2, 1], [2, 2, 2]]) output3D = np.zeros(shape=(key_idx2D.shape[0], len(key_idx), max_out + 1)) key_idx2D = key_idx[np.newaxis, :] # convert to 3D out_idx = out_idx[np.newaxis, :] idx3D = (key_idx2D, out_idx) np.add.at(output3D, idx3D, 1) #IndexError: index 2 is out of bounds for axis 0 with size 2
๐ŸŒ
Pythoninformer
pythoninformer.com โ€บ python-libraries โ€บ numpy โ€บ index-and-slice
PythonInformer - Indexing and slicing numpy arrays
February 4, 2018 - Notice the syntax - the i and j values are both inside the square brackets, separated by a comma (the index is actually a tuple (2, 1), but tuple packing is used). The example picks row 2, column 1, which has the value 8. This compares with the syntax you might use with a 2D list (ie a list of lists):
๐ŸŒ
APXML
apxml.com โ€บ courses โ€บ essential-numpy-pandas โ€บ chapter-3-numpy-array-indexing-slicing โ€บ accessing-single-elements
Access NumPy Array Elements
Visual representation of 2D array indexing. The row index comes first, followed by the column index. The highlighted cell arr2d[1, 1] corresponds to the element at row index 1 and column index 1. The concept naturally extends to arrays with more dimensions. For an N-dimensional array, you provide ...
๐ŸŒ
Programiz
programiz.com โ€บ python-programming โ€บ numpy โ€บ array-indexing
Numpy Array Indexing (With Examples)
Note: In 3D arrays, slice is a 2D array that is obtained by taking a subset of the elements in one of the dimensions. Let's see an example. import numpy as np # create a 3D array with shape (2, 3, 4) array1 = np.array([[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]) # access a specific element of the array element = array1[1, 2, 1] # print the value of the element print(element) # Output: 22
๐ŸŒ
NumPy
numpy.org โ€บ devdocs โ€บ user โ€บ how-to-index.html
How to index ndarrays โ€” NumPy v2.6.dev0 Manual
To get the indices of each maximum or minimum value for each (N-1)-dimensional array in an N-dimensional array, use reshape to reshape the array to a 2D array, apply argmax or argmin along axis=1 and use unravel_index to recover the index of the values per slice: >>> x = np.arange(2*2*3).reshape(2, ...
๐ŸŒ
Python Like You Mean It
pythonlikeyoumeanit.com โ€บ Module3_IntroducingNumpy โ€บ AdvancedIndexing.html
Advanced Indexing โ€” Python Like You Mean It
The index-arrays must have the same shape as one another, and this common shape determines the shape of the resulting array. This is a form of advanced indexing, and thus a copy of the parent arrayโ€™s data is created. NumPy also permits the use of a boolean-valued array as an index, to perform advanced indexing on an array.