Boolean Masks
Where Replace
Replace each element that fails a condition with a fixed value. A loop uses a
ternary expression to keep each value if it is non-negative, substituting 0
otherwise. The trace shows result accumulating one element per iteration,
with negative values silently replaced.
By hand
Loop over values. For each v, append v if v >= 0 else append 0.
Python's conditional expression (x if cond else y) evaluates to x when
cond is True and y when False.
naive.py
Replay: real traced execution (multi-file project)
values = [3, -1, 5, -2, 0, 4]
result = []
for v in values:
result.append(v if v >= 0 else 0)
print('RESULT:', result)
values ← [3, -1, 5, -2, 0, 4]
1values = [3, -1, 5, -2, 0, 4]2result = []values this step[3, -1, 5, -2, 0, 4]valuesresult ← []
1values = [3, -1, 5, -2, 0, 4]2result = []3for v in values:values this step[]resultv ← 3
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step3vresult ← [3]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[] → [3]resultv ← -1
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step3 → -1vresult ← [3, 0]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[3] → [3, 0]resultv ← 5
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step-1 → 5vresult ← [3, 0, 5]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[3, 0] → [3, 0, 5]resultv ← -2
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step5 → -2vresult ← [3, 0, 5, 0]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[3, 0, 5] → [3, 0, 5, 0]resultv ← 0
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step-2 → 0vresult ← [3, 0, 5, 0, 0]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[3, 0, 5, 0] → [3, 0, 5, 0, 0]resultv ← 4
2result = []3for v in values:4 result.append(v if v >= 0 else 0)values this step0 → 4vresult ← [3, 0, 5, 0, 0, 4]
3for v in values:4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this step[3, 0, 5, 0, 0] → [3, 0, 5, 0, 0, 4]resultfor v in values:
2result = []3for v in values:4 result.append(v if v >= 0 else 0)stdout ← RESULT: [3, 0, 5, 0, 0, 4]
4 result.append(v if v >= 0 else 0)5print('RESULT:', result)values this stepRESULT: [3, 0, 5, 0, 0, 4]stdout
With NumPy
np.where(a >= 0, a, 0) applies the same logic elementwise: where the
condition is True it takes the corresponding element of a, where False it
uses 0. No explicit loop is needed.
library.py
import numpy as np
values = [3, -1, 5, -2, 0, 4]
a = np.array(values)
result = np.where(a >= 0, a, 0)
print('shape:', result.shape)
print('dtype:', result.dtype)
print('values:', result.tolist())
print('RESULT:', result.tolist())
shape: (6,)
dtype: int64
values: [3, 0, 5, 0, 0, 4]
RESULT: [3, 0, 5, 0, 0, 4]
Implementation notes
np.where(cond, x, y)is the vectorized ternary.xandycan be scalars or arrays of the same shape ascond— all three are broadcast together.- This pattern is commonly used for clamping: replace values below a floor
(
np.where(a < lo, lo, a)) or above a ceiling, or to zero out negatives before a log transform. np.wherealways evaluates bothxandybefore selecting — there is no short-circuit. Side effects inxoryrun regardless of the condition.- For the equivalent pure-Python pattern see
map-transformin the python-data-basics book. - Shape, dtype, and values are shown explicitly here because
ndarray.__repr__output varies with NumPy version and print options.