NumPy Crash Course
NumPy Crash Course
Crash
Course
ABBAS ALI
NumPy Crash Course eBook
Table Of Contents
Introduction
Set-Up
Chapters:
2. NumPy Datatypes
6. Array Indexing
7. Array Slicing
8. Array Reshaping
Source code
What’s Next?
Introduction
Hey there!
The fact that you are reading this course tells me you want to build a career around one of the
following fields,
Data Analytics
Machine Learning
Deep Learning
NLP
Computer Vision
If you have done a little bit of Google search about what tools to learn to get into one of the
above fields, you know by now that after learning Python you need to start learning the Python
libraries.
And the first Python library that everyone prefers to learn is NumPy.
We learn NumPy first because every other library such as Pandas, SciPy, Matplotlib,
TensorFlow, PyTorch, and more are built on top of NumPy.
NumPy is the base of many popular libraries that we use to store and manipulate data thus if
you try to learn other libraries without learning NumPy you’re likely to struggle to grasp the
concepts.
Congratulations — You made a good choice to learn NumPy and this course will help you do
that.
In the world of Data, everything is just numbers or an array of numbers. Let’s say you are
working with images, the image needs to be converted into an array of numbers if we want to
work with it.
Learning NumPy is a must if you want to get into Data Science, Data Analytics, Machine
Learning (ML), or anything related to Artificial Intelligence (AI).
You may ask, Do I need to learn NumPy if I want to get into Deep Learning (DL), Natural
Language Processing (NLP), or Computer Vision (CV)?
I hope now you know how important it is for you to learn NumPy if you want to build a career
around AI and its related fields.
Before we move on, I want you to do a little set-up for coding because you are going to learn
NumPy in a code-first approach.
I don’t want you to just skim and read through the chapters, I want you to open your laptop,
grab a cup of coffee if you want, have this course on one tab, and on the other tab you should
have Google Colab Notebook.
After learning each topic you should execute the code on Google Colab Notebook.
The only prerequisite to take this course is knowledge of basic Python. If you know at least a
little bit of Python you will be able to go through this course with ease.
(If you don’t know Python yet, grab my FREE “Python for Absolute Newbies” ebook. It covers
all the basic topics. Use this link 👉
https://abbasaliebooks.gumroad.com/l/pythonforabsolutenewbies)
If you don’t know how to set up Google Colab read the next Chapter.
Set-Up
Step 5: Now you have a fresh notebook to start your NumPy Learning Journey.
Let’s code.
First things first, you are going to start by importing the NumPy library with its very famous
alias np.
After that, check the version of your NumPy library using np.__version__.
import numpy as np
np.__version__
# 1.26.4
As of writing this code, my NumPy version is 1.26.4. You might have a newer version if you're
running this code at a later date.
It’s time to create your first NumPy array using a Python list (l = [1, 2, 3, 4]).
(I assume you are executing the code snippets on your Google Colab, if you are not coding
along then you are not going to learn anything. So, please code along.)
In Google Colab, we don't need to use the print() function. We can simply write the variable
name and run the cell to see its output.
You know that [1, 2, 3, 4] is a Python list but when we pass the list inside
the np.array() function it gets turned into an array. To be specific a 1D (One-Dimensional)
array.
You may ask, why do we want to convert a list into an array? What is the use of doing that?
When it comes to lists, it can store elements with different datatypes (we will learn about
datatypes in the next chapter) and it stores them in random memory locations which makes the
Whereas when it comes to the array, it only stores elements of similar datatypes, and all the
elements are stored in a contiguous or continuous memory location. This makes arrays faster
than lists.
In the upcoming chapters, we will see what are datatypes and how to create 2D, 3D, and 4D
arrays.
It’s a great start already, let’s move to the next chapter, NumPy Datatypes.
As I already told you, the only prerequisite for taking this course is knowing basic Python. If
you know basic Python you know what are datatypes.
Datatypes in NumPy are no different from datatypes in Python. We got the same,
str (e.g. ‘a’, ‘Ali’, ‘cherry’, “code”, ‘YOU ARE AWESOME’, etc…)
In NumPy, we have an attribute(you will learn about attributes soon) called dtype to know the
datatype of an Array. We have many attributes in NumPy, we will learn about them in depth in
Chapter 4.
int
# OUTPUT: dtype('int64')
The 64 in (’int64’) suggests that each element in the array takes up 64 bits (8 bytes) of space.
If you want to reduce the memory usage you can change the data type from ‘int64’ to ‘int32’ or
‘int16’.
# OUTPUT: dtype('int32')
If you don’t specify any value in the dtype parameter NumPy takes 64 bits as default.
Exercise: Now try changing the dtype parameter to ‘int16’ and run the cell.
str
When each element inside the array is enclosed in single or double quote the array consists of
string elements.
# OUTPUT: dtype('<U1')
# OUTPUT: dtype('<U12')
We got ‘<U12’ because the biggest string in our array is ‘Hello World!’ and its length is 12.
Exercise: Now create an array with a different set of elements with different lengths and
see what you get.
We can also convert an array containing int elements into str by passing ‘str’ inside the dtype
parameter. See the code below,
# OUTPUT: dtype('<U1')
float
You can do the same thing that we did with the int datatype to change the bit value from 64 to
32 or 16.
bool
True and False are the only two elements of type bool.
Now, it’s time to learn how to create arrays with different dimensions.
Each dimension can be called using different terms such as scalar, vector, matrix, and tensor.
0D - Scalar
1D - Vector
2D - Matrix
3D or more - Tensor
Scalar (0D)
d0 = np.array(6)
d0, d0.ndim
# OUTPUT: (array(6), 0)
In the previous chapter, we say the dtype attributes which was used to know the datatype of
an array. Similarly, the ndim used in the above code is also an attribute that is used to know the
number of dimensions of an array.
(You don’t have to worry too much about the attributes, we will cover them in the next Chapter)
Vector (1D)
d1 = np.array([1, 2, 3, 4])
d1, d1.ndim
Matrix (2D)
d2 = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
d2, d2.ndim
When an array has both rows and columns, it is considered a 2D array or a matrix.
(If you have worked on any Machine Learning project you would know that when splitting the
dataset, we split them into two parts namely, features and labels. The features will have
multiple columns and rows exactly like a matrix but the labels will only have a single column
very much like a vector).
The above paragraph is out of the scope of this course thus if you didn’t understand anything
you don’t have to worry.
Just keep in mind that a matrix has both rows and columns but a vector only has a single
column.
Tensor (3D)
d3 = np.array([[[1, 2, 3],
[4, 5, 6]],
[[7, 8, 9],
[10, 11, 12]]])
d3, d3.ndim
Tensor (4D)
[[ 5, 6],
[ 7, 8]]],
[[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]]]), 4) """
You may ask, what types of data have these many dimensions?
Images—4D tensors
Video—5D tensors
Now you know how to create arrays of different dimensions using NumPy but before moving to
the next chapter, see the below image to understand the structures of scalar, vector, matrix,
and tensor.
If you take a person and list his attributes it would look something like this 👇,
Height: 5’7
Weight: 50 kg
Age: 24
etc…
dtype - Datatype
shape - Shape of the array (which is just the number of rows and columns depending on
the dimensions)
dtype
We have already seen this, so let’s not spend more time on this.
Exercise: Create different sets of arrays and find their datatype using the dtype attribute.
ndim
Again, we have seen this already but let’s just quickly go over them.
# OUTPUT: (1, 2, 3)
In the above code, I created 3 arrays namely, arr4, arr5, and arr6. All these 3 arrays have
different dimensions, shapes, and sizes.
shape
arr4 - (4, )
arr5 - (2, 3)
arr6 - (2, 2, 3)
See arr4 it has just one set of square brackets ([]). And in that one set of square brackets, we
got 4 elements namely, 1, 2, 3, 4.
Now see arr5 it has two sets of square brackets. In the first set of square brackets, we got 2
elements namely, [1, 2, 3], [4, 5, 6], and in the second set of square brackets, we got 3
elements each namely, 1, 2, 3 and 4, 5, 6.
[1, 2, 3]
[4, 5, 6]
The above matrix has 2 rows and 3 columns thus the shape is (2, 3).
The first set of square brackets has 2 elements → [[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]
The second set of square brackets has 2 elements each → [1, 2, 3], [4, 5, 6] and [7, 8, 9], [10,
11, 12]
The third set of square brackets has 3 elements each → 1, 2, 3 | 4, 5, 6 and 7, 8, 9 | 10, 11, 12
size
It gives the value of the number of actual elements present in the array.
Just count how many numbers are present in an array that is the size of that array. As simple
as that.
Now the next two attributes itemsize and nbytes are related to memory consumption. Let’s see
how they work.
itemsize
# OUTPUT: (8, 8, 8)
If you remember one of our previous lessons about datatypes you know that when we create
an array of integers by default it will be in the dtype of ‘int64’ which means each element in the
array takes up 8 bytes of memory.
The itemsize attribute gives us the memory consumption of a single element in the array.
# OUTPUT: (4, 8, 8)
We just changed the dtype of arr4 from ‘int64’ to ‘int32’ because of that its single elements
memory consumption is reduced from taking up 8 bytes to 4 bytes.
Exercise: Try to change the dtype of arr5 and arr6 to ‘int16’ and see what happens
nbytes
In the itemsize section, we say that a single element in arr4 takes up 4 bytes of memory and in
arr4 we got a total of 4 elements(1, 2, 3, 4) thus 4 x 4 = 16 nbytes.
For arr5, a single element holds 8 bytes of memory space. We have a total of 6 elements in it.
Thus, 8 x 6 = 48 nbytes.
It’s time to learn how to create arrays using some NumPy functions.
Till now we have been creating arrays by ourselves. But there are a few functions in NumPy
that allow us to create arrays from scratch.
You might not understand the use of these functions now but as you advance in your learning
journey everything everything will start to make sense to you.
As a beginner, have an open mind and learn the basics. Over time, you'll see how these
concepts fit together.
Below are the list of functions we are going to learn in this Chapter:
ones()
full()
arange()
linspace()
random()
randint()
eyes()
zeros:
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
Now you know how to create arrays filled with zeros in different dimension.
ones:
Now, just 0s and 1s. We can fill an array with any number we want by using the full() method.
full:
f = np.full((2, 4), 9)
f
arange:
This is one of the most used built-in functions compared to other built-in functions in NumPy.
a = np.arange(2, 21, 2)
a
The parameter values (2, 21, 2) stand for (start, stop, step), which means it starts at 2 and ends
at 21, and it skips the 2nd value after each value.
We will be using this function a lot throughout this course, so use this function and try to
create different arrays.
linspace:
l = np.linspace(1, 2, 10)
l
"""
The linspace() function finds a specified number of values between a given two numbers.
In the above code, the first two parameter values (1 and 2) are the given two numbers. The
linspace() functions will find 10 values of equidistance from each other.
# OUTPUT: array([ 2., 4., 6., 8., 10., 12., 14., 16., 18., 20.])
random:
Inside the NumPy library there is a module called random. And inside this random module we
got a method named random. That’s why we got np.random.random() in the below code.
We can only specify the shape. In the below code, I specified the shape as (5, 4).
If you want to create random number of your choice. You need to use the randint() method.
randint:
The above code creates an array with elements of random number between 4 and 10 of shape
(3, 9).
If you want to get the same set of values every time you run the cell you need to set a seed
value.
In the below code, I seed the seed value as 38. But the seed value can be anything.
If you set the same seed value as me you will get the same set of random elements like me. If
you use a different seed value you will get a different set of random elements.
np.random.seed(38)
ri = np.random.randint(4, 10, (3,9))
ri
After setting the seed value using the seed() method, the output will not change every time I
run the cell.
eye:
Finally, the eye() method generates a matrix that will contain 1’s diagonally, see the below code,
e = np.eye(5, dtype=int)
e
You will know the use of this function once you start learning about Computer Vision (CNN,
Filters, and more).
Exercise: Try out all the functions by yourself with different set of parameters.
Every element inside an array has an index value. The index value starts with 0.
The index value of the first element is 0, the second element is 1, the third element is 2, and so
on.
In this chapter, we are going to fetch the elements from arrays of different dimensions using
their index values.
np.random.seed(45)
arr1 = np.random.randint(10, size=10)
arr1
You will get the same set of values if you use the same seed value as me (45).
Let’s fetch some values from the array using their index.
# (3, 0, 5)
When you count the index from the beginning it starts with 0, 1, 2, etc…
But if you count the index from the reverse it starts with -1, -2, -3, etc…
For example, for an array like [1, 2, 3, 4, 5]. The reverse index value of 1 is -5, 2 is -4, 3 is -3, 4
is -2, and 5 is -1.
Let’s use the reverse index value and grab the last 3 values from the array arr1.
# (9, 5, 1)
We can not only grab the values using their index we can also change the value with a new
value.
Exercise: Try changing the values of other elements in arr1 using their reverse index.
Now you know how to fetch and change the element in a 1D array.
"""
Because this is a 2 dimensional array it has 2 index positions for each of the dimensions.
[6, 8, 7, 8, 5] 0
[2, 8, 1, 6, 4] 1
[8, 4, 6, 4, 9] 2
index 0 1 2 3 4
0 6 8 7 8 5
1 2 8 1 6 4
2 8 4 6 4 9
If you want to fetch the first row you can simply use arr2[0].
But if you want to fetch only the element 6 in the first row you need to use arr2[0, 0]. ([row,
column])
arr2[0, 0]
# OUTPUT: 6
Remember, rows and columns when fetching values from a 2D array. Specify the row first then
the column.
# OUTPUT: (6, 8, 6)
arr2[1, 2]
# OUTPUT: 1
# OUTPUT: 9
# OUTPUT: 8
"""
I hope by now you know how to fetch and change value from both 1D and 2D NumPy arrays.
Exercise: Try to find the output of the code examples below by yourself.
[[2, 6, 7, 0],
[0, 2, 9, 2],
[6, 0, 9, 6]]])
arr3[1, 1, 3]
# OUTPUT: ___
arr3[-2, 1]
# OUTPUT: ___
arr3[1]
# OUTPUT: ___
arr3[0] = 0
arr3
[[2, 6, 7, 0],
[0, 2, 9, 2],
[6, 0, 9, 6]]])
"""
With the help of slicing we can break arrays into different pieces.
Even for slicing the arrays, we are going to use the index values of the elements.
arr4 = np.arange(10)
arr4
We created an array with 10 elements. Let’s say I want the slice [4, 5, 6, 7] from this array. Then
I would do something like,
arr4[4: 8]
Here is an example,
arr4[1: 10: 2]
Note: If you give the stop value as 10 it will only take up to 9. If you give the stop value as 9 it
will only take up to 8.
Exercise: Try a different set of [start: stop: step] values and make a slice.
np.random.seed(67)
arr5 = np.random.randint(1, 10, (3, 4))
arr5
"""
If I want the middle row [4, 7, 4, 8] from this 2D array, I will do something like,
arr5[1:2]
index 0 1 2 3
0 4 6 6 8
1 4 7 4 8
2 9 6 4 7
arr5[0:2, 1:3]
Let’s use negative indexing (or reverse indexing) and slice out the middle two columns.
index 0 or -4 1 or -3 2 or -2 3 or -1
0 or -3 4 6 6 8
1 or -2 4 7 4 8
2 or -1 9 6 4 7
arr5[-3:, 1:-1]
"""
[-3:] - If you don’t specify anything after (:) it means it will fetch all the rows starting from -3.
[1: -1] - Here we are using both normal and reverse indexing. We are starting from the 1st index
to the last index which is -1.
Hey, wait.
[[7, 7, 5, 9],
[4, 2, 5, 9],
[3, 8, 1, 8]]])
"""
Exercise: Explore your curiosity and slice the above 3D array into different pieces.
Done?
Great.
Let’s learn how to reshape NumPy arrays from one dimension to another.
3x3
9x1
1x9
2x5
5x2
10 x 1
1 x 10
arr7.reshape(3, 3)
"""
2x5
5x2
10 x 1
1 x 10
Let’s see one more example of how to reshape an array with 20 elements.
5 X 4 = 20
arr8.reshape(5, 4)
"""
4 X 5 = 20
arr8.reshape(4, 5)
"""
2 X 5 X 2 = 20
arr8.reshape(2, 5, 2)
[[11, 12],
[13, 14],
[15, 16],
[17, 18],
[19, 20]]])
"""
NumPy array concatenation and splitting are two important and opposite array operations.
Array concatenation is joining two or more arrays together. We can join two arrays either
horizontally or vertically. We will see that in-depth in this chapter.
Array splitting is splitting a single array into two or more pieces. We split the elements in the
array using their indices.
You will understand these two operations better via code examples than definitions. So, let’s
quickly create some arrays and try out these operations.
Array Concatenation
a1 = np.arange(1, 5)
a2 = np.arange(5, 9)
a1, a2
In the above code, I created two sample arrays a1 and a2 using arange().
np.concatenate([a1, a2])
But when it comes to 2D or 3D arrays there are some additional methods that we can use to
join the two arrays in different axes.
Don’t worry if you didn’t understand the above paragraph. The following code example will
make things clear.
a3 = np.arange(1, 10).reshape(3, 3)
a4 = np.arange(10, 19).reshape(3, 3)
a3, a4
"""
"""
To join them horizontally, we need to pass the value 1 in the axis parameter.
"""
vstack() &
hstack()
to do the same thing. Using vstack() we can join the arrays vertically. Using hstack() we can
join them horizontally.
np.vstack([a3, a4])
"""
"""
Exercise: Create three 2D arrays and use concatenation(), vstack(), and hstack() and
perform different join operations.
Array Splitting
a5 = np.arange(1, 10)
a5
np.split(a5, [4])
The value [4] is just the index value where I want to make the split.
We can also split the array into more than 2 pieces let’s see how to do that.
So, the elements before the index 3 will be the first split ([1, 2, 3]).
The elements from index 3 to index 5(value on index 5 not included) will be the second split
([4, 5]).
The elements from index 5 to index 7(value on index 7 not included) will be the third split ([6,
7]).
Finally, every element from index 7 will be the fourth split ([8, 9]).
array([[ 3, 4],
[ 7, 8],
[11, 12],
[15, 16],
[19, 20]])]
"""
We got,
vsplit() &
hsplit()
np.vsplit(a6, [3])
"""
np.hsplit(a6, [2])
array([[ 3, 4],
[ 7, 8],
[11, 12],
[15, 16],
[19, 20]])]
"""
Finally. You have reached the last chapter of the NumPy Crash Course—You are awesome.
There are plenty of Ufuncs (Universal Functions) in NumPy but we are not going to look at
every one of them.
In this chapter, we are going to cover the Ufuncs of three major operations namely,
Arithmetic Operations
Comparison Operations
Arithmetic Operations
add()
subtract()
multiply()
divide()
floor_divide()
power()
mod()
Let’s create a sample array and execute all the above operations on it.
add()
np.add(arr1, 5)
The above code adds 5 to all the elements in the array arr1.
subtract()
np.subtract(arr1, 2)
This code subtracts 2 from all the elements in the array arr1.
multiply()
np.multiply(arr1, 10)
# OUTPUT: array([ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
divide()
# OUTPUT: array([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1
floor_divide()
np.floor_divide(arr1, 4)
power()
np.power(arr1, 2)
mod()
np.mod(arr1, 2)
mod() gives us the reminder value of all the elements after being divided by 2.
Exercise: Perform all the arithmetic operations on a 2D array and see how it works.
mean()
median()
std()
var()
min()
max()
Let’s find the mean, median, standard deviation (std), variance var), minimum value (min), and
maximum value (max)
mean()
np.mean(arr2)
# OUTPUT: 3.0
median()
np.median(arr2)
# OUTPUT: 3.0
np.std(arr2)
# OUTPUT: 1.4142135623730951
var()
np.var(arr2)
# OUTPUT: 2.0
min()
np.min(arr2)
# OUTPUT: 1
max()
np.max(arr2)
# OUTPUT: 5
Done.
Exercise: Use the aggregate functions on a 2D array. Just explore your curiosity. Try
different things and see how they work.
equal()
less()
less_equal()
greater()
greater_equal()
not_equal()
import numpy as np
a1 = np.array([1, 2, 3, 4])
a2 = np.array([1, 0, 3, 7])
a1, a2
We are going to compare the elements inside the arrays a1 and a2.
When using comparison method we get an array of elements containing ‘True’ or ‘False’ based
on the comparison.
equal()
np.equal(a1, a2)
The first and third elements in both the arrays a1 and a2 are 1 and 3 respectively, thus the first
and third element of the output is ‘True’
np.less(a1, a2)
less_equal()
np.less_equal(a1, a2)
greater()
np.greater(a1, a2)
greater_equal()
np.greater_equal(a1, a2)
not_equal()
np.not_equal(a1, a2)
Congratulations!!!
That’s a wrap!!!
What’s Next?
The fact that you are reading this tells me how disciplined you are in learning.
Not many people can do what you have just done. Most people would have quit after
completing just 4 or 5 chapters but you completed all the 10 chapters (I believe you did) and
are eager to know what to do next.
I really appreciate that. You will go a long way and achieve more and more in your life.
https://medium.com/@iabbasali
https://www.youtube.com/@Abbas_AIi
https://abbasaliebooks.gumroad.com/
Source Code
👇.
All the code examples used in this course can be found in my GitHub
https://github.com/AbbasAli01/AbbasAli/blob/main/NumPy_Crash_Course.ipynb