Indexing, Slicing, Boolean Selection
On this page
When working with data, we often need to locate, extract, or modify specific parts of an array. NumPy offers several ways to do this — through indexing, slicing, and Boolean selection. These techniques allow us to examine or manipulate subsets of our data without copying it unnecessarily, which makes NumPy both efficient and powerful.
Let’s begin by creating a simple one-dimensional array that we’ll use throughout this section:
import numpy as np
arr = np.arange(10)
print(arr)[0 1 2 3 4 5 6 7 8 9]
The result shows a NumPy array containing the integers from 0 to 9.
Indexing
Indexing means selecting a single element (or a group of elements) from an array using its position. Like most programming languages, NumPy uses zero-based indexing — this means counting starts at 0, not 1. So the first element is at index 0, the second at index 1, and so on.
Let’s access a few elements:
print(arr[0]) # first element
print(arr[3]) # fourth element
print(arr[-1]) # last element0
3
9
The negative index -1 refers to the last element, -2 to the second-to-last, and so on. This feature is convenient when you want to access elements from the end of an array without knowing its exact length.
Indexing also works for multidimensional arrays. In two dimensions, the first index refers to the row, and the second refers to the column.
matrix = np.array([[10, 20, 30],
[40, 50, 60],
[70, 80, 90]])
print(matrix[0, 0]) # element at first row, first column
print(matrix[1, 2]) # element at second row, third column
print(matrix[2, -1]) # last element in the last row10
60
90
Understanding indexing is fundamental, because it forms the basis for slicing and more advanced selection techniques.
Slicing
Slicing allows you to select a range of elements from an array rather than just one. It uses a simple syntax:
array[start:stop:step]startis the index where the slice begins (inclusive).stopis where it ends (exclusive).stepdefines how many elements to skip between each selection.
Let’s explore some examples using our previously defined array arr:
print(arr[2:6]) # elements from index 2 up to (but not including) 6
print(arr[:5]) # first five elements
print(arr[5:]) # elements from index 5 to the end
print(arr[::2]) # every second element[2 3 4 5]
[0 1 2 3 4]
[5 6 7 8 9]
[0 2 4 6 8]
Notice how the colon : acts as a flexible slicing operator. If you omit start, it begins at 0; if you omit stop, it continues to the end; if you omit step, it assumes 1.
Slicing also extends naturally to two-dimensional arrays:
print(matrix[0:2, 1:3]) # rows 0–1, columns 1–2
print(matrix[:, 0]) # all rows, first column
print(matrix[1, :]) # second row, all columns[[20 30]
[50 60]]
[10 40 70]
[40 50 60]
Here, : means “select everything” along that dimension. This makes it possible to extract submatrices (smaller rectangular sections of data) efficiently — something especially useful when analyzing datasets stored in matrix form.
Boolean Selection
Boolean selection allows us to extract elements that meet certain conditions. Instead of referring to positions, we refer to values — letting the data itself decide what gets selected.
Suppose we want to select all even numbers from our array:
even_numbers = arr[arr % 2 == 0]
print(even_numbers)[0 2 4 6 8]
Here, arr % 2 == 0 produces a Boolean array of True and False values:
[True False True False True False True False True False]
NumPy then keeps only the elements corresponding to True.
We can combine multiple conditions using logical operators:
&means “and”|means “or”~means “not”
For example, to select all numbers greater than 3 and less than 8:
subset = arr[(arr > 3) & (arr < 8)]
print(subset)[4 5 6 7]
Boolean selection is one of the most powerful features in NumPy. It allows you to filter data directly based on its content — for instance, selecting all authors with more than ten published works, or filtering out missing or invalid entries in a dataset.