Skip to content

Numpy Array Indexing and Selection

Now that we know how to build arrays, let's look at how to pull values our of an array using indexing, and also slicing off sections of an array.

Indexing

This is how to select elements and groups of elements from an array.

import numpy as np
arr = np.arange(0,11)  # create an array
arr
Output:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

Similar to selecting an element from a python list, we use the bracket notation to select an element from an array at a given index.

arr[4]
Output:
4

Slicing

We can also use slicing to select a range of entries in an array.

arr[2:5]
Output:
array([2, 3, 4])

These methods for selection also work on two-dimensional arrays.

randarr = np.random.randint(0,50,9)
randarr = randarr.reshape(3,3)
randarr
Output:
array([[ 6,  5, 18],
       [ 7, 46, 11],
       [37, 29, 38]])

We can select a single entry by specifying the row/column indices.

randarr[1,2]
Output:
11

Using a single value will select the entire row.

randarr[1]
Output:
array([[ 7, 46, 11]])

Slicing with multi-dimensional arrays works in the same way.

randarr[1:,:]    # rows 1 onwards, all columns
Output:
array([[ 7, 46, 11],
       [37, 29, 38]])
randarr[2,:]  # using slicing to select bottom row
Output:
array([37, 29, 38])

Broadcasting

NumPy arrays differ from a normal Python list because of their ability to broadcast. This is the ability to write a range of values to the array using slicing.

arr[0:5] = 100
Output:
array([100, 100, 100, 100, 100, 5, 6, 7, 8, 9, 10])

Warning

When using array slicing and broadcasting we need to be aware that data is not copied, slicing only provides a view of the original array. This means you could overwrite values if you aren't careful.

arr = np.arange(0,11)
slice_of_arr = arr[0:6]
slice_of_arr
Output:
array([0, 1, 2, 3, 4, 5])
slice_of_array[0:6] = 99
arr
Output:
array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10])

Broadcasting can be done for multi-dimensional arrays.

arr2D = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2D[0:2,0:2] = 99
arr2D
Output:
array([[99, 99,  3],
       [99, 99,  6],
       [ 7,  8,  9]])

Fancy Indexing

Fancy indexing allows for the selection of rows or columns in any order. This is best illustrated with an example.

my_arr = np.zeros((10,10))
for i in range(10):
    my_arr[i]=i
my_arr  
Output:
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
       [7., 7., 7., 7., 7., 7., 7., 7., 7., 7.],
       [8., 8., 8., 8., 8., 8., 8., 8., 8., 8.],
       [9., 9., 9., 9., 9., 9., 9., 9., 9., 9.]])
my_arr[[2,8,5]]  # selection of rows 2, 8, and 5
Output:
array([[2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
       [8., 8., 8., 8., 8., 8., 8., 8., 8., 8.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.]])
my_arr[[2,4,6,8]]=0  # fancy selection and broadcasting
my_arr
Output:
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [7., 7., 7., 7., 7., 7., 7., 7., 7., 7.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [9., 9., 9., 9., 9., 9., 9., 9., 9., 9.]])

Conditional Selection

Given an array, if we wish to select only entries that satisfy some criteria we can use a boolean mask. As a straightforward example, we will select entries from an array using a boolean mask of alternating True/False values.

arr = np.arange(0,10)
bool_arr = np.array([True, False, True, False, True, False,
                     True, False, True, False,])
arr[bool_arr]
Output:
array([0, 2, 4, 6, 8])

Now we will create a boolean mask by using a boolean expression on the entries of the array. Then we select the entries from the array using this mask.

arr = np.arange(0,10)
bool_arr = arr > 5
bool_arr
Output:
array([False, False, False, False, False, False, True,
       True, True, True])
arr[bool_arr]
Output:
array([6, 7, 8, 9])

This could also be done in one line as follows.

arr[arr > 5]
Output:
array([6, 7, 8, 9])

As usual, selection only returns a view of the array. Therefore, we can use broadcasting to overwrite specific portions of the array.

In the example above, bool_arr is a boolean which contains True for the indices in which the entries of the array are greater than \(5\). We can set all these entries in the original array to 99 as follows.

arr[bool_arr] = 99
arr
Output:
array([ 0,  1,  2,  3,  4,  5, 99, 99, 99, 99])