AlgoInsight

Q&A

NumPy where() method

By AlgoInsight Team2026-06-18arraysnumpypython

Overview

np.where solves two related but distinct problems with one function: conditional selection across arrays (the three-argument form) and index lookup (the one-argument form). The three-argument form is the most common - it's the NumPy way to say "pick from A where condition is True, else from B," done over whole arrays at once without any loop.

graph TD
    A["np.where(condition, x, y)"] --> B["Vectorized ternary:<br/>True positions → x, False → y"]
    C["np.where(condition)"] --> D["Returns tuple of index arrays<br/>where condition is True"]
    style A fill:#1e1b4b,color:#fff

Three-Argument Form: Conditional Selection

import numpy as np

arr = np.array([10, -5, 20, -3, 7])

result = np.where(arr > 0, arr, 0)   # keep positives, zero out negatives
print(result)   # [10  0 20  0  7]

# Equivalent Python loop (don't write this in NumPy code):
# [arr[i] if arr[i] > 0 else 0 for i in range(len(arr))]

x and y can be scalars, arrays, or broadcast-compatible combinations:

a = np.array([1, 2, 3, 4, 5])
b = np.array([10, 20, 30, 40, 50])
mask = np.array([True, False, True, False, True])

np.where(mask, a, b)   # [1 20 3 40 5]  - a where True, b where False

Replace values conditionally

grades = np.array([45, 72, 88, 31, 95])
labels = np.where(grades >= 60, "pass", "fail")
# ['fail' 'pass' 'pass' 'fail' 'pass']

Multiple conditions with np.select

For more than two categories, chain np.where or use np.select:

conditions = [grades >= 90, grades >= 70, grades >= 50]
choices    = ["A", "B", "C"]
np.select(conditions, choices, default="D")
# ['D' 'B' 'A' 'D' 'A']

One-Argument Form: Finding Indices

np.where(condition) returns a tuple of arrays (one per dimension) of the indices where the condition is True:

arr = np.array([1, -2, 3, -4, 5])
indices = np.where(arr < 0)
print(indices)        # (array([1, 3]),)  - tuple with one array for 1-D
print(arr[indices])   # [-2 -4]           - index back into the array

For 2-D arrays, the result tuple has two arrays (row indices, column indices):

m = np.array([[1, -2], [3, -4]])
rows, cols = np.where(m < 0)
# rows = [0, 1], cols = [1, 1]  - positions (0,1) and (1,1)

Comparison with Boolean Masking

Boolean masking (arr[arr > 0]) is typically cleaner for filtering, but np.where shines when you want to replace values rather than select them:

arr[arr < 0] = 0                # boolean mask assignment - in-place
result = np.where(arr < 0, 0, arr)  # same result, returns new array

Broadcasting

x and y broadcast normally with each other and with the condition:

matrix = np.arange(9).reshape(3, 3)
np.where(matrix % 2 == 0, matrix, -1)
# even values kept; odd values become -1

Performance

np.where executes in compiled C over contiguous arrays - typically 10–100× faster than an equivalent Python loop or list comprehension on large arrays. For ML and data processing workloads (replacing values, creating label arrays, masking anomalies), it's the standard tool.

Why This Matters in Interviews

Data-science/NumPy interviews use np.where to test vectorized thinking. Key points: the three-argument form is a vectorized ternary (avoid Python loops for this); the one-argument form returns indices (like nonzero); both operate over the whole array without explicit iteration; broadcasting applies to x and y; and np.select generalizes to multiple conditions. Showing you'd reach for np.where rather than a list comprehension for array conditionals signals NumPy fluency.

Common Pitfalls

References

More answers