Boolean Masking & np.where
Definition
Boolean masking filters or conditionally modifies array data using arrays of
True/Falsevalues.np.where()andnp.select()extend this to conditional value assignment — NumPy’s vectorized equivalent of an if/else or CASE-WHEN expression.
Boolean Masks (Recap from Indexing)
arr = np.array([1, -2, 3, -4, 5])
mask = arr > 0 # array([True, False, True, False, True])
arr[mask] # [1, 3, 5] — filter
arr[mask].sum() # sum of only positive values
mask.sum() # count of True values (True=1, False=0)
np.count_nonzero(mask) # equivalent, often fasterCombining Conditions
(arr > 0) & (arr < 4) # AND — parentheses required due to operator precedence
(arr > 3) | (arr < -3) # OR
~(arr > 0) # NOT
np.logical_and(arr > 0, arr < 4) # explicit function form
np.logical_or(a, b)
np.logical_not(a)
np.logical_xor(a, b)np.where() — Conditional Value Selection
np.where(condition, value_if_true, value_if_false)arr = np.array([1, -2, 3, -4, 5])
np.where(arr > 0, arr, 0) # replace negatives with 0: [1, 0, 3, 0, 5]
np.where(arr > 0, "positive", "negative") # string labeling
# np.where with a single argument returns matching INDICES (like np.nonzero)
indices = np.where(arr > 0) # (array([0, 2, 4]),)
arr[np.where(arr > 0)] # equivalent to arr[arr > 0]np.select() — Multiple Conditions (Vectorized if/elif/elif/else)
scores = np.array([95, 82, 67, 45, 78])
conditions = [scores >= 90, scores >= 75, scores >= 60]
choices = ["A", "B", "C"]
np.select(conditions, choices, default="F")
# ['A', 'B', 'C', 'F', 'B']
np.selectfor multi-branch logicCleaner and faster than chaining multiple nested
np.where()calls when there are 3+ conditions.
np.any() / np.all()
np.any(arr > 100) # True if AT LEAST ONE element satisfies the condition
np.all(arr > 0) # True if ALL elements satisfy the condition
np.any(arr2d > 5, axis=0) # per-column: any value > 5?
np.all(arr2d > 0, axis=1) # per-row: all values > 0?np.nonzero() and np.flatnonzero()
np.nonzero(arr) # tuple of index arrays where condition/value is nonzero/True
np.flatnonzero(arr > 0) # flat array of indices (1D shortcut)Clipping and Conditional Capping
np.clip(arr, a_min=0, a_max=100) # cap values into [0, 100]
np.clip(arr, 0, None) # only enforce a floor (no ceiling)Masked Arrays (For Explicit “Missing” Semantics)
import numpy.ma as ma
masked = ma.masked_array(arr, mask=[True, False, False, True, False])
masked.mean() # automatically excludes masked (True) entries from computation
numpy.mavs plain boolean filtering
numpy.ma.masked_arrayis useful when you need to remember which values are invalid across many downstream operations without repeatedly re-filtering — pandas’NaNhandling (Pandas: Missing Data) solves the same problem at a higher level for tabular data.