Numpy Basics — 1. n-D Arrays Manipulation
NumPy is a Python library used a lot in data science because it allows to work with a large amount of data in an efficient way.
What makes this library so efficient is that it’s written partially in Python and mostly in C/C++.
Getting Started
The first thing to do is to install NumPy. You can do it easily with pip
:
pip install numpy
Then you can import NumPy this way:
import numpy as np
It’s a standard to import NumPy under the np
alias, most of the developers do it, so you should too.
You can now create a first array and print it:
array = np.array([1, 2, 3, 4, 5])
print(array)
print(type(array))
# [1 2 3 4 5]
# <class 'numpy.ndarray'>
Multi-Dimensional Arrays
There are no limits to the number of dimensions of your arrays. Let’s start with a 0-D array:
zero_dim_array = np.array(1)
print(zero_dim_array)
# 1
A 0-D array is just a number. Now, if we create an array of 0-D arrays, we have a 1-D array:
one_dim_array = np.array([1, 2, 3, 4, 5])
print(one_dim_array)
# [1 2 3 4 5]
If we create an array of 1-D arrays, we have a 2-D array:
two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
print(two_dim_array)
"""
[[1 2 3]
[4 5 6]]
"""
The max number of dimensions is 32, but you won’t ever use such big arrays I guess. Let’s create some more arrays:
three_dim_array = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(three_dim_array)
four_dim_array = 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]]]])
print(four_dim_array)
"""
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
"""
"""
[[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
[[[13 14 15]
[16 17 18]]
[[19 20 21]
[22 23 24]]]]
"""
You can also use ndmin
to create an array with a specific dimension number:
five_dim_array = np.array([0], ndmin=5)
print(five_dim_array)
# [[[[[0]]]]]
To check the number of dimensions in an array, you can use array.ndim
.
print(five_dim_array.ndim)
# 5
Shape
The shape of an array is a tuple representing the number of elements in each dimension. It’s an important thing to know because depending on the computations you want to do, it may require a specific shape.
We access it using array.shape
print(four_dim_array.shape)
for i in range(four_dim_array.ndim):
print(f"Dimension {i}: {four_dim_array.shape[i]}")
# (2, 2, 2, 3)
# Dimension 0: 2
# Dimension 1: 2
# Dimension 2: 2
# Dimension 3: 3
We can change the shape of arrays using array.reshape(new_shape)
. The new shape has to be compatible with the array. To explain this compatibility principle, let’s take an example.
Imagine an array with this shape: (3, 3)
. 1st dimension contains 3elements, and 2nd dimension contains 3 elements. It means the array contains 9 values because you can make 3 rows of arrays of 3 values.
With a (2, 3, 3, 1, 5)
shape, the array contains 2*3*3*1*5 = 90
values. If we want to reshape it, the other shape should be able to contain also 90 values. So a possible shape would be (10, 3, 3)
. Let’s try this:
array1 = np.array([1, 2], [3, 4], [5, 6])
print(array1.size)
print(array1.shape)
# 6
# (3, 2)
The array size is 6, so other shapes could be (2, 3)
, or (1, 6)
, or (1, 1, 1, 1, 6)
.
new_array1 = array1.reshape(2, 3)
new_array2 = array1.reshape(1, 6)
new_array3 = array1.reshape(1, 1, 1, 1, 6)
print(new_array1)
print(new_array2)
print(new_array3)
This code works! If you change the shape to something that can’t contain 6 values, it will raise an exception.
Indexing
NumPy arrays can be accessed the same way you would access multi-dimensional lists. There is also another way. Let’s check this example:
two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
print(two_dim_array[0])
print(two_dim_array[0][1])
print(two_dim_array[0, 1])
# [1 2 3]
# 2
# 2
You can also use negative indexing:
print(two_dim_array[-1][1])
# 5
Knowing how indexing works, we can now create slices:
print(two_dim_array[0][1:3])
print(two_dim_array[0, 1:3])
print(two_dim_array[0, 1:])
print(two_dim_array[-1, ::-1])
# [2 3]
# [2 3]
# [2 3]
# [6 5 4]
One more time, it works the same way as it works for lists, but with another syntax to make it clearer.
Iterating
Iterating also works the same way it works for lists. Let’s start with the simplest example, a 1-D array:
one_dim_array = np.array([1, 2, 3, 4, 5])
for x in one_dim_array:
print(x, end=" ")
# 1 2 3 4 5
No trouble here, it’s the same thing as this code:
one_dim_list = [1, 2, 3, 4, 5]
for x in one_dim_list:
print(x, end=" ")
Things get a bit more complicated when working with 2-D arrays, but still logical:
two_dim_array = np.array([[1, 2, 3], [4, 5, 6]])
for x in two_dim_array:
print(x, end=" ")
# [1 2 3] [4 5 6]
Each element of the 1st dimension is a vector, so it prints vectors. If we want to iterate over all the values, we have to use nested for loops:
for x in two_dim_array:
for y in x:
print(y, end=" ")
# 1 2 3 4 5 6
Or:
for x in two_dim_array.flat:
print(x, end=" ")
# 1 2 3 4 5 6
flat
is used to get the flattened array. We can also use array.flatten()
to create a 1-D array from an n-D array.
flat_array = two_dim_array.flatten()
print(flat_array)
print(flat_array.ndim)
print(flat_array.shape)
# [1 2 3 4 5 6]
# 1
# (6,)
Another way to iterate over all scalar elements is to use nditer
:
for x in np.nditer(two_dim_array):
print(x, end=" ")
# 1 2 3 4 5 6
With this, we can iterate over complex n-D arrays with many dimensions!
six_dim_array = 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]]]]]])
for x in np.nditer(six_dim_array):
print(x, end=" ")
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Final Note
There are still a lot of things to say about NumPy, but you have some basics now, so I’ll stop here. I’ll write another story to cover what I’ve not talked about here, so be sure to give me a follow if you don’t want to miss it!
By the way, you may wonder how such arrays can be used. There are a lot of applications. An example is a game board. Instead of using Python multi-dimensional lists, you can use NumPy arrays.
You can try to code a Tic Tac Toe game using NumPy. Here is the solution, but be sure to give it a try before checking!
To explore more of my Python stories, click here! You can also access all my content by checking this page.
If you liked the story, don’t forget to clap, comment, and maybe follow me if you want to explore more of my content :)
You can also subscribe to me via email to be notified every time I publish a new story, just click here!
If you’re not subscribed to Medium yet and wish to support me or get access to all my stories, you can use my link: