True and False values that selects elements from another array based on specific conditions. It enables fast vectorized filtering, conditional replacement, and in-place updates without slow Python loops.Boolean indexing evaluates element-wise relational operations (such as >, ==, <=) to produce Boolean arrays. These masks can be combined using bitwise operators (&, |, ~) or logical functions like np.logical_and. For conditional mapping, see where().
A boolean mask is an array of truth values matching the shape of the target array. When passed inside indexing brackets x[mask], NumPy extracts only the positions where the mask evaluates to True.
Create relational conditions and filter elements:
import numpy as np
x = np.array([5, 12, 7, 22, 3, 18])
mask = x >= 10
print("Mask:", mask) # [False True False True False True]
print("Filtered:", x[mask]) # [12 22 18]
# Combine conditions (use parentheses with & and |)
mask2 = (x >= 10) & (x % 2 == 0)
print("Combined condition filtered:", x[mask2]) # [12 22 18]
assert np.array_equal(x[mask2], np.array([12, 22, 18]))
Expected output
Mask: [False True False True False True]
Filtered: [12 22 18]
Combined condition filtered: [12 22 18]
Use np.where(cond, a_if_true, a_if_false) to construct new arrays based on conditions:
x = np.array([5, 12, 7, 22, 3, 18])
# Replace values < 10 with 0, keep others
y = np.where(x < 10, 0, x)
print("Replaced array:", y) # [ 0 12 0 22 0 18]
# Map categories
labels = np.where(x >= 15, 'high', 'low')
print("Category labels:", labels) # ['low' 'low' 'low' 'high' 'low' 'high']
Expected output
Replaced array: [ 0 12 0 22 0 18]
Category labels: ['low' 'low' 'low' 'high' 'low' 'high']
Bitwise operators require parentheses due to Python operator precedence rules. Alternatively, use logical functions:
a = np.arange(12)
m1 = (a >= 3) & (a <= 8) # Operators
m2 = np.logical_and(a >= 3, a <= 8) # Functions
print(np.array_equal(a[m1], a[m2])) # True
assert np.array_equal(a[m1], np.array([3, 4, 5, 6, 7, 8]))
Expected output
True
Apply masks along rows or element-wise across 2D matrices:
b = np.array([
[1, 2, 3],
[10, 20, 30],
[40, 50, 60]
])
# Column-wise filter: take rows where column 0 >= 10
row_mask = b[:, 0] >= 10
print("Filtered rows:
", b[row_mask])
# Element-wise mask: extract 1D array of elements >= 20
elem_mask = b >= 20
print("Filtered elements:", b[elem_mask])
assert b[row_mask].shape == (2, 3)
Expected output
Filtered rows:
[[10 20 30]
[40 50 60]]
Filtered elements: [20 30 40 50 60]
Use np.isfinite, np.isnan, and np.isinf to handle special floating-point values safely:
c = np.array([1.0, np.nan, 3.5, np.inf, -np.inf, 2.2])
finite_mask = np.isfinite(c)
print("Finite elements:", c[finite_mask])
# Replace NaNs with mean of finite values
c_fixed = np.where(np.isnan(c), np.nanmean(c), c)
print("NaN-fixed array:", c_fixed)
assert np.array_equal(c[finite_mask], np.array([1.0, 3.5, 2.2]))
Expected output
Finite elements: [1. 3.5 2.2]
NaN-fixed array: [ 1.25 2.25 3.5 inf -inf 2.2 ]
Modify elements matching a boolean condition directly in place:
d = np.arange(10)
d[d % 2 == 1] = -1
print("Updated array:", d)
assert np.array_equal(d, np.array([0, -1, 2, -1, 4, -1, 6, -1, 8, -1]))
Expected output
Updated array: [ 0 -1 2 -1 4 -1 6 -1 8 -1]
Test boolean indexing, conditional mapping with np.where, 2D masking, and run verification test suites in our interactive Google Colab companion notebook:
Launch the notebook directly in Google Colab to run live code cells or inspect the source repository on GitHub:
View on GitHubContinue exploring related array indexing and filtering functions: Indexing & Slicing, where(), and array().
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.