In [1]: import numpy as np
In [2]: a = np.array([[2,0],[3,0],[3,1],[5,0],[5,1],[5,2]])
In [3]: b = np.zeros((6,3), dtype='int32')

In [4]: b[a[:,0], a[:,1]] = 10

In [5]: b
Out[5]: 
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [10,  0,  0],
       [10, 10,  0],
       [ 0,  0,  0],
       [10, 10, 10]])

Why it works:

If you index b with two numpy arrays in an assignment,

b[x, y] = z

then think of NumPy as moving simultaneously over each element of x and each element of y and each element of z (let's call them xval, yval and zval), and assigning to b[xval, yval] the value zval. When z is a constant, "moving over z just returns the same value each time.

That's what we want, with x being the first column of a and y being the second column of a. Thus, choose x = a[:, 0], and y = a[:, 1].

b[a[:,0], a[:,1]] = 10

Why b[a] = 10 does not work

When you write b[a], think of NumPy as creating a new array by moving over each element of a, (let's call each one idx) and placing in the new array the value of b[idx] at the location of idx in a.

idx is a value in a. So it is an int32. b is of shape (6,3), so b[idx] is a row of b of shape (3,). For example, when idx is

In [37]: a[1,1]
Out[37]: 0

b[a[1,1]] is

In [38]: b[a[1,1]]
Out[38]: array([0, 0, 0])

So

In [33]: b[a].shape
Out[33]: (6, 2, 3)

So let's repeat: NumPy is creating a new array by moving over each element of a and placing in the new array the value of b[idx] at the location of idx in a. As idx moves over a, an array of shape (6,2) would be created. But since b[idx] is itself of shape (3,), at each location in the (6,2)-shaped array, a (3,)-shaped value is being placed. The result is an array of shape (6,2,3).

Now, when you make an assignment like

b[a] = 10

a temporary array of shape (6,2,3) with values b[a] is created, then the assignment is performed. Since 10 is a constant, this assignment places the value 10 at each location in the (6,2,3)-shaped array. Then the values from the temporary array are reassigned back to b. See reference to docs. Thus the values in the (6,2,3)-shaped array are copied back to the (6,3)-shaped b array. Values overwrite each other. But the main point is you do not obtain the assignments you desire.

Answer from unutbu 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 โ€บ indexing-multi-dimensional-arrays-in-python-using-numpy
Indexing Multi-dimensional arrays in Python using NumPy - GeeksforGeeks
November 4, 2025 - Indexing in multi-dimensional arrays allows us to access, modify or extract specific elements or sections from arrays efficiently. In Python, NumPy provides tools to handle this through index numbers, slicing and reshaping.
๐ŸŒ
CodeSignal
codesignal.com โ€บ learn โ€บ courses โ€บ multidimensional-arrays-and-their-traversal-in-python โ€บ lessons โ€บ exploring-the-dimensions-a-beginners-guide-to-multidimensional-arrays-in-python
Exploring the Dimensions: A Beginner's Guide to Multidimensional Arrays in Python | CodeSignal Learn
Here's an example of a 2-dimensional array: ... In this example, array is a 2-dimensional array, just like a 3-storey 'apartment building,' where every floor is an inner list. All indices in Python arrays are 0-based. Let's say you want to visit an apartment on the second floor (index 1) and ...
๐ŸŒ
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.
๐ŸŒ
freeCodeCamp
freecodecamp.org โ€บ news โ€บ multi-dimensional-arrays-in-python
Multi-Dimensional Arrays in Python โ€“ Matrices Explained with Examples
December 11, 2025 - In this example, we create a 2-dimensional array using the np.array() function, and then access an element at row 1, column 2 using indexing. We then modify an element at row 0, column 3 using indexing again.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ indexing-multi-dimensional-arrays-in-python-using-numpy
Indexing Multi-dimensional arrays in Python using NumPy | GeeksforGeeks
April 28, 2025 - Syntax:numpy_array.flatten(order='C') order:'C' means to flatten in row-major.'F' means to flatten in column-major.'A' means to flatten in column-major ... NumPy (Numerical Python) is a Python library that comprises of multidimensional arrays and numerous functions to perform various mathematical and logical operations on them.
Top answer
1 of 2
67
In [1]: import numpy as np
In [2]: a = np.array([[2,0],[3,0],[3,1],[5,0],[5,1],[5,2]])
In [3]: b = np.zeros((6,3), dtype='int32')

In [4]: b[a[:,0], a[:,1]] = 10

In [5]: b
Out[5]: 
array([[ 0,  0,  0],
       [ 0,  0,  0],
       [10,  0,  0],
       [10, 10,  0],
       [ 0,  0,  0],
       [10, 10, 10]])

Why it works:

If you index b with two numpy arrays in an assignment,

b[x, y] = z

then think of NumPy as moving simultaneously over each element of x and each element of y and each element of z (let's call them xval, yval and zval), and assigning to b[xval, yval] the value zval. When z is a constant, "moving over z just returns the same value each time.

That's what we want, with x being the first column of a and y being the second column of a. Thus, choose x = a[:, 0], and y = a[:, 1].

b[a[:,0], a[:,1]] = 10

Why b[a] = 10 does not work

When you write b[a], think of NumPy as creating a new array by moving over each element of a, (let's call each one idx) and placing in the new array the value of b[idx] at the location of idx in a.

idx is a value in a. So it is an int32. b is of shape (6,3), so b[idx] is a row of b of shape (3,). For example, when idx is

In [37]: a[1,1]
Out[37]: 0

b[a[1,1]] is

In [38]: b[a[1,1]]
Out[38]: array([0, 0, 0])

So

In [33]: b[a].shape
Out[33]: (6, 2, 3)

So let's repeat: NumPy is creating a new array by moving over each element of a and placing in the new array the value of b[idx] at the location of idx in a. As idx moves over a, an array of shape (6,2) would be created. But since b[idx] is itself of shape (3,), at each location in the (6,2)-shaped array, a (3,)-shaped value is being placed. The result is an array of shape (6,2,3).

Now, when you make an assignment like

b[a] = 10

a temporary array of shape (6,2,3) with values b[a] is created, then the assignment is performed. Since 10 is a constant, this assignment places the value 10 at each location in the (6,2,3)-shaped array. Then the values from the temporary array are reassigned back to b. See reference to docs. Thus the values in the (6,2,3)-shaped array are copied back to the (6,3)-shaped b array. Values overwrite each other. But the main point is you do not obtain the assignments you desire.

2 of 2
4

TL;DR: Use advanced indexing: b[*a.T] = 10

You can also transpose the index array a, convert the result into a tuple and index the array b and assign a value. Converting the index array into a tuple (or unpacking it inside a []) ensures that multidimensional indexing works as expected. This is assignment by advanced indexing.

a = np.array([[2, 0], [3, 0], [3, 1], [5, 0], [5, 1], [5, 2]])
b = np.zeros((6,3), dtype ='int32')

b[*a.T] = 10
# or
b[tuple(a.T)] = 10
# or 
b[(*a.T,)] = 10
# or 
b[(*a.T.tolist(),)] = 10

All of them produce the expected output of

array([[ 0,  0,  0],
       [ 0,  0,  0],
       [10,  0,  0],
       [10, 10,  0],
       [ 0,  0,  0],
       [10, 10, 10]])
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ python_data_structure โ€บ python_2darray.htm
Python - 2-D Array
One index referring to the main or parent array and another index referring to the position of the data element in the inner array.If we mention only one index then the entire inner array is printed for that index position.
Find elsewhere
๐ŸŒ
Pluralsight
pluralsight.com โ€บ blog โ€บ tech guides & tutorials
Working with Numpy Arrays: Indexing & Slicing | Pluralsight
To access elements in this array, use two indices. One for the row and the other for the column. Note that both the column and the row indices start with 0. So if I need to access the value โ€˜10,โ€™ use the index โ€˜3โ€™ for the row and index ...
Top answer
1 of 1
2

Ah, I think I now get what you are after. Fancy indexing is documented here in detail. Be warned though that - in its full generality - this is quite heavy stuff. In a nutshell, fancy indexing allows you to take elements from a source array (according to some idx) and place them into a new array (fancy indexing allways returns a copy):

source = np.array([10.5, 21, 42])
idx = np.array([0, 1, 2, 1, 1, 1, 2, 1, 0])

# this is fancy indexing
target = source[idx]

expected = np.array([10.5, 21, 42, 21, 21, 21, 42, 21, 10.5])
assert np.allclose(target, expected)

What is nice about this is that you can control the shape of the resulting array using the shape of the index array:

source = np.array([10.5, 21, 42])
idx = np.array([[0, 1], [1, 2]])

target = source[idx]

expected = np.array([[10.5, 21], [21, 42]])
assert np.allclose(target, expected)
assert target.shape == (2,2)

Where things get a little more interesting is if source has more than one dimension. In this case, you need to specify the indices of each axis so that numpy knows which elements to take:

source = np.arange(4).reshape(2,2)
idxA = np.array([0, 1])
idxB = np.array([0, 1])

# this will take (0,0) and (1,1)
target = source[idxA, idxB]

expected = np.array([0, 3])
assert np.allclose(target, expected)

Observe that, again, the shape of target matches the shape of the index used. What is awesome about fancy indexing is that index shapes are broadcasted if necessary:

source = np.arange(4).reshape(2,2)
idxA = np.array([0, 0, 1, 1]).reshape((4,1))
idxB = np.array([0, 1]).reshape((1,2))

target = source[idxA, idxB]

expected = np.array([[0, 1],[0, 1],[2, 3],[2, 3]])
assert np.allclose(target, expected)

At this point, you can understand where your exception comes from. Your source.ndim is 4; however, you try to index it with a 2-tuple (indLargest2ndAxis, 1). Numpy will interpret this as you trying to index the first axis using indLargest2ndAxis, the second axis using 1, and all other axis using :. Clearly, this doesn't work. All values of indLargest2ndAxis would have to be between 0 and 4 (inclusive), since they would have to refer to positions along the first axis of x.

What my suggestion of x[..., indLargest2ndAxis, 1] does is tell numpy that you wish to index the last two axes of x, i.e., you wish to index the third axis using indLargest2ndAxis, the fourth axis using 1, and : for anything else.

This will produce a result since all elements of indLargest2ndAxis are in [0, 10), but will produce a shape of (5, 10, 5, 10, 6) (which is not what you want). Being a bit hand-wavy, the first part of the shape (5, 10) comes from the ellipsis (...), aka. select everything, the middle part (5, 10, 6) comes from indLargest2ndAxis selecting elements along the third axis of x according to the shape of indLargest2ndAxis and the final part (which you don't see because it is squeezed) comes from selecting index 1 along the fourth axis.


Moving on to your actual problem, you can entirely dodge the fancy indexing bullet and do the following:

x = np.arange(1000).reshape(5, 10, 10, 2)
order = x[..., 0]
values = x[..., 1]
idx = np.argpartition(order, 4)[..., 4:]
result = np.take_along_axis(values, idx, axis=-1)

Edit: Of course, you can also use fancy indexing; however, it is more cryptic and doesn't scale as nicely to different shapes:

x = np.arange(1000).reshape(5, 10, 10, 2)
indLargest2ndAxis = np.argpartition(x[..., 0], 4)[..., 4:]
result = x[np.arange(5)[:, None, None], np.arange(10)[None, :, None], indLargest2ndAxis, 1]
Top answer
1 of 3
6

Another option is multidimensional list-of-locations indexing:

import numpy as np

ncol = 10  # 10 in your case
nrow = 500  # 500 in your case
# just creating some test data:
x = np.arange(ncol*nrow).reshape(nrow,ncol)
y = (ncol * np.random.random_sample((nrow, 1))).astype(int)

print(x)
print(y)
print(x[np.arange(nrow),y.T].T)

The syntax is explained here. You basically need an array of indices for each dimension. In the first dimension this is simply [0,...,500] in your case and the second dimension is your y-array. We need to transpose it (.T), because it has to have the same shape as the first and the output array. The second transposition is not really needed, but gives you the shape you want.

EDIT:

The question of performance came up and I tried the three methods mentioned so far. You'll need line_profiler to run the following with

kernprof -l -v tmp.py

where tmp.py is:

import numpy as np

@profile
def calc(x,y):
    z = np.arange(nrow)
    a = x[z,y.T].T  # mine, with the suggested speed up
    b = x[:,y].diagonal().T  # Christoph Terasa
    c = np.array([i[j] for i, j in zip(x, y)])  # tobias_k

    return (a,b,c)

ncol = 5  # 10 in your case
nrow = 10  # 500 in your case

x = np.arange(ncol*nrow).reshape(nrow,ncol)
y = (ncol * np.random.random_sample((nrow, 1))).astype(int)

a, b, c = calc(x,y)
print(a==b)
print(b==c)

The output for my python 2.7.6:

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    3                                           @profile
    4                                           def calc(x,y):
    5         1            4      4.0      0.1      z = np.arange(nrow)
    6         1           35     35.0      0.8      a = x[z,y.T].T
    7         1         3409   3409.0     76.7      b = x[:,y].diagonal().T
    8       501          995      2.0     22.4      c = np.array([i[j] for i, j in zip(x, y)])
    9                                           
    10         1            1      1.0      0.0      return (a,b,c)

Where %Time or Time are the relevant columns. I don't know how to profile memory consumption, someone else would have to do that. For now it looks like my solution is the fastest for the requested dimensions.

2 of 3
4

While not really intuitive from a syntactic perspective

X[:,Y].diagonal()[0]

will give you the values you're looking for. The fancy indexing selects from each row of X all values in Y, and diagonal selects only those at the indexes where i == j. The indexing with [0] at the end just flattens the 2d array.

๐ŸŒ
NumPy
numpy.org โ€บ doc โ€บ stable โ€บ user โ€บ basics.indexing.html
Indexing on ndarrays โ€” NumPy v2.5 Manual
So note that x[0, 2] == x[0][2] though the second case is more inefficient as a new temporary array is created after the first index that is subsequently indexed by 2. ... NumPy uses C-order indexing. That means that the last index usually represents the most rapidly changing memory location, unlike Fortran or IDL, where the first index represents the most rapidly changing location in memory. This difference represents a great potential for confusion. Basic slicing extends Pythonโ€™s basic concept of slicing to N dimensions.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ numpy-indexing
Numpy Array Indexing - GeeksforGeeks
September 22, 2026 - Array indexing in NumPy is used to access, select, and modify elements of an array. NumPy supports indexing for one-dimensional and multidimensional arrays, along with slicing, Boolean indexing, fancy indexing, and tools such as np.newaxis and ...
๐ŸŒ
SciPy
docs.scipy.org โ€บ doc โ€บ โ€บ numpy-1.11.0 โ€บ user โ€บ basics.indexing.html
Indexing โ€” NumPy v1.11 Manual
May 29, 2016 - Single element indexing for a 1-D ... indices for indexing from the end of the array. ... Unlike lists and tuples, numpy arrays support multidimensional indexing for multidimensional arrays....
๐ŸŒ
Python Like You Mean It
pythonlikeyoumeanit.com โ€บ Module3_IntroducingNumpy โ€บ AdvancedIndexing.html
Advanced Indexing โ€” Python Like You Mean It
As you may guess, in order to perform this variety of indexing on an \(N\)-dimensional array, we must specify \(N\) index-arrays; one for each dimension. Each of the \(N\) index-arrays must have the same shape, and their common shape determines the shape of the resulting array.
Top answer
1 of 3
6

We can compute the linear indices and then use np.take -

np.take(lut, np.ravel_multi_index(arr.T, lut.shape)).T

If you are open to alternatives, we can reshape the indices array to 2D, convert to tuples, index into the data array with it, to give us 1D, which could be reshaped back to 2D -

lut[tuple(arr.reshape(-1,arr.shape[-1]).T)].reshape(arr.shape[:2])

Sample run -

In [49]: lut = np.random.randint(11,99,(13,13,13))

In [50]: arr = np.arange(12).reshape([2,2,3])

In [51]: lut[ arr[:,:,0],arr[:,:,1],arr[:,:,2] ] # Original approach
Out[51]: 
array([[41, 21],
       [94, 22]])

In [52]: np.take(lut, np.ravel_multi_index(arr.T, lut.shape)).T
Out[52]: 
array([[41, 21],
       [94, 22]])

In [53]: lut[tuple(arr.reshape(-1,arr.shape[-1]).T)].reshape(arr.shape[:2])
Out[53]: 
array([[41, 21],
       [94, 22]])

We can avoid the double transposing for the np.take approach, like so -

In [55]: np.take(lut, np.ravel_multi_index(arr.transpose(2,0,1), lut.shape))
Out[55]: 
array([[41, 21],
       [94, 22]])

Generalize to multi-dimensional arrays of generic dimensions

This could be generalized to ndarrays of generic no. of dims, like so -

np.take(lut, np.ravel_multi_index(np.rollaxis(arr,-1,0), lut.shape))

The tuple-based approach should work without any change.

Here's a sample run for the same -

In [95]: lut = np.random.randint(11,99,(13,13,13,13))

In [96]: arr = np.random.randint(0,13,(2,3,4,4))

In [97]: lut[ arr[:,:,:,0] , arr[:,:,:,1],arr[:,:,:,2],arr[:,:,:,3] ]
Out[97]: 
array([[[95, 11, 40, 75],
        [38, 82, 11, 38],
        [30, 53, 69, 21]],

       [[61, 74, 33, 94],
        [90, 35, 89, 72],
        [52, 64, 85, 22]]])

In [98]: np.take(lut, np.ravel_multi_index(np.rollaxis(arr,-1,0), lut.shape))
Out[98]: 
array([[[95, 11, 40, 75],
        [38, 82, 11, 38],
        [30, 53, 69, 21]],

       [[61, 74, 33, 94],
        [90, 35, 89, 72],
        [52, 64, 85, 22]]])
2 of 3
1

I did not try in 3-dimensions. But in 2-dimensions I get the result I want with using numpy.take :

np.take(np.take(T,ix,axis=0), iy,axis=1 )

Perhaps you can expand that to 3-dimensions.

As an example I can adress with two 1-dim arrays for the indices ix and iy the 2-dimensional stencil for the discrete Laplace equation,

ฮ”T = T[ix-1,iy] + T[ix+1, iy] + T[ix,iy-1] + T[ix,iy+1] - 4*T[ix,iy]

Introducing for a leaner writing:

def q(ฮฆ,kx,ky):
    return np.take(np.take(ฮฆ,kx,axis=0), ky,axis=1 )

then I can run the following python code with numpy.take:

nx = 6; ny= 10
T  = np.arange(nx*ny).reshape(nx, ny)

ix = np.linspace(1,nx-2,nx-2,dtype=int) 
iy = np.linspace(1,ny-2,ny-2,dtype=int)

ฮ”T = q(T,ix-1,iy)  + q(T,ix+1,iy)  + q(T,ix,iy-1)  + q(T,ix,iy+1)  - 4.0 * q(T,ix,iy)
Top answer
1 of 1
3
import numpy as np              # Line 01
y = np.zeros((3,3))             # Line 02
y = y.astype(np.int16)          # Line 03
y[1,1] = 1                      # Line 04
x = np.ones((3,3))              # Line 05
t = (1-y).astype(np.int16)      # Line 06
print(t)                        # Line 07
print(x[t])                     # Line 08
x[(1-y).astype(np.int16)] = 0   # Line 09
print(x)                        # Line 10

Line 02:

Creates a two-dimensional 3 x 3 ndarray of zeros. y is a name that is made to point to this ndarray.

Line 03:

Sets the data-type of each element of y, to 16-bit integer.

Line 04:

Sets the element of y at the intersection of the middle row and middle column, to 1.

Line 05:

Creates a two-dimensional 3 x 3 ndarray of ones. x is a name that is made to point to this ndarray.

Line 06:

The subtraction (1-t) results in several scalar subtractions (1- elem), where elem is each element of t. The result will be another ndarray, having the same shape as t, and having the result of the subtraction (1- elem), as its values. That is, the values of the ndarray (1-t) will be:

[[1-t[0,0], 1-t[0,1], 1-t[0,2]],
 [1-t[1,0], 1-t[1,1], 1-t[1,2]],
 [1-t[2,0], 1-t[2,1], 1-t[2,2]]]

Since t is full of zeros, and a lone 1 at the intersection of the middle row and middle column, (1-t) will be a two-dimensional ndarray full of ones, with a lone 0 at the intersection of the middle row and middle column.

Line 07:

Prints t

Line 08:

Things get a little tricky from here. What is happening here is called "Combined Advanced and Basic Indexing" (https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html#combining-advanced-and-basic-indexing). Let's go through the specifics, step-by-step. First, notice that x, is a two-dimensional ndarray, taking another integer ndarray t as an index. Since x needs two indices to be supplied, t will be taken to be the first of those two indices, and the second index will be implicitly assumed to be :. So, x[t] is first interpreted as x[t,:]. The presence of these two indices, where one index is an array of integers t, and the other index is a slice :, results in the situation that is called "Combined Advanced and Basic Indexing".

Now, what exactly happens in this "Combined" scenario? Here goes: First, the shape of the result will get contributions from the first index t, as well as from the second index :. Now t has the shape (3,3), and hence the contribution of t to the shape of the result of x[t,:], is to supply the outermost (leftmost) dimensions of the result shape. Hence the result shape will begin with (3,3,). Now, the contribution of : to the shape of x[t,:] is based on the answer to the question: On which dimension of x is the : being applied ? The answer is -- the second dimension (since : is the second index within x[t,:]). Hence the contribution of : to the result shape of x[t,:] is 3 (since 3 is the length of the second dimension of x). To recap, we have deduced that the result shape of x[t] will be that of x[t,:], which in turn will be (3,3,3). This means x[t] will be a three-dimensional array, even though x itself is only a two-dimensional array.

Note that in the shape (3,3,3) of the result, the first two 3s were contributed by the advanced index t, and the last 3 was contributed by the implicit basic index :. These two indexes t and : also use different ways to arrive at their respective contributions. The 3,3, contribution that came from the index t is just the shape of t itself. It doesn't care about the position of t among the indexes, in the expression x[t,:] (it doesn't care whether t occurs before : or : appears before t). The 3 contribution that came from the index : is the length of the second dimension of x, and we consider the second dimension of x because : is the second index in the expression x[t,:]. If x had the shape (3,5) instead of (3,3), then the shape of x[t,:] would have been (3,3,5) instead of (3,3,3).

Now that we've deduced the shape of the result of x[t] to be (3,3,3), let us move on to understand how the values themselves will get determined, in the result. The values in the result are obviously the values at positions [0,0,0], [0,0,1], [0,1,2], [0,1,0], [0,1,1], [0,1,2], [0,2,0], [0,2,1], [0,2,2], and so on. Let's walk through one example of these positions, and you will hopefully get the drift. For our example, let's look at the position [0,1,2] in the result. To get the value for this position, we will first index into the t array using the 0 and the 1. That is, we find out t[0,1], which will be 1 (refer to the output of print(t)). This 1, which was obtained at t[0,1], shall be taken to be our first index into x. The second index into x will be 2 (remember that we are discussing the position [0,1,2] within the result, and trying to determine the value at that position). Now, given these first and second indices into x, we get from x the value to be populated at position [0,1,2] of x[t].

Now, x is just full of ones. So, x[t] will only consist of ones, even though the shape of x[t] is (3,3,3). To really test your understanding of what I've said so far, you need to fill x with diverse values: So, temporarily, comment out Line 05, and have the following line in its place:

x = np.arange(9).reshape((3,3))    # New version of Line 05

Now, you will find that print(x[t]) at Line 08 gives you:

[[[3 4 5]
  [3 4 5]
  [3 4 5]]

 [[3 4 5]
  [0 1 2]
  [3 4 5]]

 [[3 4 5]
  [3 4 5]
  [3 4 5]]]

Against this output, test your understanding of what I've described above, about how the values in the result will get determined. (That is, if you've understood the above explanation of x[t], you should be able to manually re-construct this same output as above, for print (x[t]).

Line 09:

Given the definition of t on Line 06, Line 09 is equivalent to x[t], which, as we saw above, is equivalent to x[t, :] = 0.

And the effect of the assignment x[t, :] = 0 is the same as the effect of x[0:2, :] = 0.

Why is this so? Simply because, in x[t, :]:

  1. The index values generated by the index t are 0s and 1s (since t is an integer index array consisting of only 0s and 1s)
  2. The index values generated by the index : are 0, 1, and 2.
  3. We are referring only to positions within x that correspond to combinations of these index values. That is, x[t, :] relates only to the those positions x[i,j], where i takes values 0 or 1, and j takes values 0,1, or 2. That is, x[t, :] relates only to the positions x[0,0], x[0,1], x[0,2], x[1,0], x[1,1], x[1,2], within the array x.
  4. So, the assignment statement x[t, :] = 0 assigns the value 0 at these positions in x. Effectively, we are assigning the value 0 into all three columns in the first two rows of x, and we are leaving the third row of x unchanged.

Line 10:

Prints the value of x after the above assignment.