Welcome to Engineering Python.
This is a Python programming course for engineers.
In this video, I'll talk about NumPy array indexing and slicing.
We'll start with 1D array indexing and sliding.
First, we need to import numpy as np.
Let's create a 1D array a.
It contains the squared values of the integer numbers from 0 to 4.
If we want to access the second number in this array, we use a followed by a pair of
brackets then a number, 2 inside the brackets.
Note in Python, indexes start from 0.
So, the element with an index 2 is 4.
If we want to access several elements in sequence, we can use the slicing like this, a followed
by a pair of brackets and then from 2 to 5, including 2 but not including 5.
So, the result is 4, 9, and 16.
In this example, because we didn't specify the start point, by default it starts from
index 0.
This 4 means we go up to index 4 but not including 4.
This 2 means a step of 2, or we select every other element.
Let's count.
Select 0, skip 1, select 2, skip 3, not including 4.
So the result is just the elements in locations 0 and 2.
They are 0 and 4.
We can also change some elements in an array.
In this example, the numbers 0 and 4 will be replaced by -100.
If we want to put the array in reverse order, we can use this expression.
No start, no end, the step is -1.
This is the result.
This operation is not done in place.
So, a does change afterwards.
Now, let's talk about 2D array indexing.
We create a 2 by 3 2D array, a, using the reshape function.
This is the zeroth row, this is the first row.
To access the first row, we use a followed by a pair of brackets, and a number 1 inside
the brackets.
This is the first row, which is a 1D array.
To access the element at the cross of the first row and first column, we further append
another index 1 inside a pair of brackets like this.
The element at the intersection of the first row and the first column is 4.
A more common way to access a single element is to put the row index and the column index
in the same pair of brackets, separated by a comma, like this.
The result is 4.
Let's compare 2D array indexing with the indexing of a list of lists.
b is a list of two lists.
b one means the first element.
It is a sublist.
b one one will access the first element in this sublist.
The number is 4.
However, this representation, b one comma one will not work for lists.
If you run this, it will create an error.
Now, let's create another, larger 2D array using array reshaping.
It is a 5-row by 5-column array.
We will use this array to demonstrate 2D array slicing.
In the following examples, we should remember that Python indexes always start from 0.
In this statement, we will access the elements that are in the first row, and the second
and third columns.
In this image, these elements are marked by red cells.
They are two numbers, 7 and 8.
This statement will access the elements starting from the third row, going up to the end row,
and starting from the third column, going up to the end column.
These four elements are marked by green cells.
This statement will access the elements in all the rows and the first column.
These five elements are marked by purple cells.
The result is a 1D row array because we already talked about this in the previous video, NumPy
does not differentiate between 1D row arrays and 1D column arrays.
In this statement, because we didn't specify the start and the end for rows but we did
specify the step, which is 2, we will select the zeroth row, the second row, and the fourth
row.
We will also select the second column, the fourth column.
The resultant cells are marked in yellow.
There is another type of indexing for NumPy arrays.
They are called advanced indexing or fancy indexing.
Basically, we access the elements in one NumPy array using another NumPy array as the index.
Let's create a 1D NumPy array, a, with 5 elements.
This is the data array.
Then we create another 1D array, i, with 4 elements.
This is the index array.
We assemble them in this format, so the data will come from the data array, and the indexes
will come from the index array.
That means, we are selecting the third element, which is 9, the first element, which is 1,
the third element, which is 9 again, and the zeroth element, which is 0.
The resultant array always has the same shape as the index array.
In this case, it also has 4 elements.
Fancy indexing can also be applied to 2D index arrays.
This a is still a 1D data array with 5 elements.
We create an index array j, which is a 2 by 2 array.
If we assemble them in this way, we are accessing the zeroth element in a, which is 0, the third
element, which is 9, the second element, which is 4, and the first element, which is 1.
Again, the elements in the resultant array come from the data array, and the shape is
determined by the index array.
So, it's a 2 by 2 2D array.
For fancy indexing, both the data array and the index arrays can be 2D arrays.
Here is an example.
c is a 3 by 4 2D data array.
i is a 2 by 2 2D index array for the row indexes.
j is a 2 by 2 2D index array for the column indexes.
If we assemble them in this way, we are selecting the elements in the second column, the row
information is determined by the index array i.
This element will be zeroth row and second column, this will be first row and second
column, this will be first row and second column, and the last one will be the second
row and second column.
The result is a 2 by 2 array.
Similarly, if we assemble them in this way, the row information is determined by the index
array i, and the column information is determined by the index array j.
The result is another 2 by 2 array.
We can also change the values of these elements in the data array c to -1.
So, these values in the corresponding locations are updated as a result.
Boolean arrays can also be used as indexes for fancy indexing.
Let's see some examples.
We create a data array, a.
It's a 3 by 3 2D array.
We create another array b, by comparing a with 4.
This is an element-wise comparison.
So the result is another boolean array with True or False values.
This is our index array.
We assemble them in this way.
The result is a 1D array.
The shape is not the same as the index array any more.
These elements are those in a and greater than 4.
We can assign a new value -1 to these locations so the data array is changed to this.
The last four numbers are replaced by -1.
We further define a boolean array i.
It will serve as the index array for the row indexes.
Another boolean array j.
It will serve as the index array for the column indexes.
In this statement, the row information will come from i, and we will consider all the
columns.
The result is the first and second rows of the data array because only these indexes
are True.
In this statement, the column information will come from j, and we will consider all
the rows.
The result is the zeroth and second columns of the data array because only these indexes
are True.
I need to add a little bit more about fancy indexing.
Let's create a 5 by 5 array like this one.
I represent this array in this image.
Suppose we want to access the elements in the red cells in the diagonal line.
We can find their indexes and put them into two tuples.
This one is 0 and 0.
So, 0 and 0.
This one is 2 and 2.
So, 2 and 2.
This one is 4 and 4.
So, 4 and 4.
The resultant array is just the one we wanted.
If we want to access the green cells, these two and these four, we can do it in this way.
These elements are located in the first, third, and fourth row.
So, we have a list, with 1, 3, and 4.
They are the row information.
These elements are located in the third and last columns.
So, this starts from 3, goes to the end column.
This array is what we wanted.
If we want to access the purple cells, we can use a boolean mask like this.
The data type is bool.
We only want the three middle elements.
So, their values are ones, and the other two on the sides are zeros.
This is the boolean array we created.
These elements are located on the first row, so, this row index is 1.
The column information is supplied by this mask.
This is the result array.
It's what we wanted.
Lastly, if we want to access the yellow cells, we can use a more advanced concept called
the index mesh.
We create an index mesh using the ix underscore function.
The first argument is the row information.
Because the yellow cells are located in the first and fourth rows.
The second argument is the column information.
Because the columns are not continuous, we use the r underscore operator to stack them
together in a row.
This the created index mesh.
We can use this mesh directly as the index of the data array.
The result is just what we wanted.
At the end of this video, I'll talk about array stacking and splitting.
We create a 2 by 2 2D array a, which contains 0 and positive numbers.
We also create another 2 by 2 2D array b, which contains 0 and negative numbers.
The vstack function will merge these two arrays vertically, a on top of b.
Note that this argument is a list.
A tuple also works.
However, this does not work because it's two arguments and not a tuple.
The hstack function will merge these two arrays horizontally, a in front of b.
Note that this argument is a tuple.
A list also works.
Array splitting is the reverse operation compare to stacking.
We create a 3 by 3 array and use it to demonstrate the splitting.
The vsplit function passes 2 arguments, the array a, and how many parts it will be split
into.
In this case, it's 3.
This array will be split vertically into three parts.
The result is three rows.
The hsplit function also passes 2 arguments, the array a, and how many parts it will be
split into.
It's also 3.
This array will be split horizontally into three parts.
The result is three columns.
Okay, that was all about NumPy array indexing and slicing.
The course materials are available on YouTube and GitHub.
You can watch the course videos in sequence.
If you like this video, please subscribe and share.
I'm Yong Wang.
Thanks for watching.