13 minutes read

In this topic, we continue discussing NumPy. We will focus on new ways of creating arrays, as well as on methods of their indexing and slicing. The introduction to NumPy showed the simplest way to create an array — converting a Python list using np.array(). But there are other ways we may need to know.

Array range and evenly spaced array

The first function that helps to create arrays in NumPy, is np.arange(). It is similar to the built-in range() generator of numbers, but np.arange() returns an array. Let's have a look at the example.

array_1 = np.arange(5)
print(array_1)  # [0 1 2 3 4]

You can also create an array by specifying a start element, a stop element, and a step: np.arange(start, stop, step). The default step value equals to 1. Note that the start element is included in the range while the stop element is not.

array_2 = np.arange(5, 9)
array_3 = np.arange(5, 6, 0.2)
print(array_2)  # [5 6 7 8]
print(array_3)  # [5. 5.2 5.4 5.6 5.8]

If you want to space all the elements in your array evenly, np.linspace() can help you. It takes the start value, the end value, and the num parameter which is the total number of elements. The default num value is 50, so in the second example below, there will be 50 elements in the array array_5, evenly spaced between 21 and 23. As opposed to the np.arange() function, the end value in np.linspace() is always included in the array.

array_4 = np.linspace(21, 23, num=5)
array_5 = np.linspace(21, 23)
print(array_4)   # [21.  21.5 22.  22.5 23. ]
print(array_5)  # [21.         21.04081633 21.08163265 21.12244898 ... 22.95918367 23.        ]

Arrays filled with ones and zeros

Sometimes we need an array consisting of only zeroes or only ones. In NumPy, there are easy ways to create them. np.zeros() and np.ones() create new dimensioned arrays filled with the corresponding values.

array_6 = np.ones((3, 2))
array_7 = np.zeros(7)
print(array_6)
# [[1. 1.]
#  [1. 1.]
#  [1. 1.]]
print(array_7)  # [0. 0. 0. 0. 0. 0. 0.]

The np.zeros_like() and np.ones_like() functions are similar to the previous ones, but they return an array of ones or zeros with the same shape and type as the given arrays.

x = np.array([[1, 1, 1], [2, 2, 2]])
y = np.array([1, 2, 3, 4, 5])
array_8 = np.ones_like(x)
array_9 = np.zeros_like(y)
print(array_8)
# [[1 1 1]
#  [1 1 1]]
print(array_9)  # [0 0 0 0 0]

Converting NumPy arrays to Python lists

Finally, when you do not need to work with arrays anymore, you can easily transform them into lists. NumPy provides the array.tolist() function.

array_10 = np.array([[1, 2], [3, 4]])
lst1 = array_10.tolist()
print(lst1)  # [[1, 2], [3, 4]]

If we attempt to use the list(array) function on numpy arrays, it will also return a list but its elements will be numpy arrays.

array_11 = np.array([[5, 2], [7, 4]])
lst2 = list(array_11)
print(lst2)  # [array([5, 2]), array([7, 4])]
print(type(lst2[0]))  # <class 'numpy.ndarray'>

Indexing in arrays

Now, once we know how to create arrays, it is time to learn how to get access to their elements. Just like with Python lists, we can access the elements using indices. If you use a one-dimensional array in your program, there is no difference with how list indices work. However, when you face an n-dimensional array, do not forget about some key operations.

Let's have a look at the example and discuss it.

array_12 = np.array([[1, 12, 31], [4, 45, 64], [0, 7, 89]])
print(array_12[2, 2])  # 89
print(array_12[2][2])  # 89

First of all, we created a two-dimensional array. Suppose, we are interested in getting the last value. The idea of multidimensional indexing is quite easy: if you have two dimensions, the first value addresses the row of your array, the second one addresses the index of the value you are searching for. You can see that the result of array_12[2, 2] and array_12[2][2] is the same. The first case is more efficient, however, because when we write array_12[2][2], a new temporary array is created after the first index that is subsequently indexed by 2.

Similarly, if you have three dimensions, you need to print three values to execute multidimensional indexing, etc. Let's look at the three-dimensional example below.

array_13 = np.array([[[1, 12, 31], [4, 45, 64], [0, 7, 89]]])
print(array_13[0, 1, 1])  # 45
print(array_13[0][1][1])  # 45

If you print an index that is out of the bounds, it will cause an error in your program.

Slicing in arrays

NumPy arrays can also be sliced like lists in Python. Slicing a one-dimensional array is the same as slicing a Python list, so our main task is to understand how to slice n-dimensional arrays. Look at the example below:

array_14 = np.array([[100, 101, 102],
                 [103, 104, 105],
                 [106, 107, 108],
                 [109, 110, 111]])
print(array_14[1:3, 1])   # [104 107]

We start by creating a two-dimensional array array_14 with four rows. When we write array_14[1:3, 1], the first part addresses the slice of the rows to be taken into account, then the second part chooses an element of each row. As a result, we have a one-dimensional array.

Let's have a look at some more examples. array_15 below is a three-dimensional array. Just like in Python, we can use the negative index to choose elements from the end — the last two-dimensional array [[11, 12, 13, 14, 15], [16, 17, 18, 19, 20]] in this case. Then we just make a full slice of the array with the help of the : operator, and at last, in each row, we choose a particular slice.

array_15 = np.array([[[1, 2, 3, 4, 5],
                 [6, 7, 8, 9, 10]],
                 [[11, 12, 13, 14, 15],
                 [16, 17, 18, 19, 20]]])
print(array_15[-1, :, 1:4])
# [[12 13 14]
#  [17 18 19]]

In the example below, we access a particular slice from the first two-dimensional array [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]:

print(array_15[0, :, 1:4])
# [[2 3 4]
#  [7 8 9]]

In array_16 we extract every row and element with a given step.

# two-dimensional array
array_16 = np.array([[1, 2, 3, 4, 5],
                 [5, 4, 3, 2, 1],
                 [6, 7, 8, 9, 10],
                 [10, 9, 8, 7, 6],
                 [11, 12, 13, 14, 15]])
print(array_16[::2, ::2])
# [[ 1  3  5]
#  [ 6  8 10]
#  [11 13 15]]

As you can see, slicing operations are the same as with Python lists. But here, we apply them with the dimensions in mind. This can lead to some errors, especially with high-dimensional arrays, so we need to be very careful.

Conclusion

In this topic, we have learned how to:

  • create arrays using different methods,
  • transform arrays into lists,
  • index and slice multidimensional arrays.

Now it's high time to move on to some practical tasks. Practice makes perfect!

82 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo