Express a Checked Array Computation
Compare a readable loop with its whole-array equivalent and choose an exact or tolerance-aware check.
A whole-array expression can state repeated numerical work in one line. That shorter form is useful only when we can still explain what it computes. A clear loop gives us a reference: it exposes the repeated steps, and we can compare its result with the array expression.
We will use the same raw measurement table and calibration rule:
The table has shape (3, 2): three observations by two sensors. Every raw
reading should be multiplied by 0.5, then increased by 1.0.
Write the Repeated Work as a Loop
The loop visits each observation and sensor position:
[[ 2. 6.]
[ 3. 8.]
[ 4. 10.]]
At position [1, 0], the loop calculates 4.0 × 0.5 + 1.0 = 3.0. At
position [2, 1], it calculates 18.0 × 0.5 + 1.0 = 10.0. The same rule
applies at every position; only the selected raw value changes.
The copy gives the result its own array before the loop assigns calibrated
values into it. The source raw remains unchanged.
Q1. Trace one loop assignment
What value does the loop assign to loop_calibrated[0, 1]?
Compute it first, then check your number.
HintInspect the matching source position
raw[0, 1] is 10.0. Substitute it into value * 0.5 + 1.0.
SolutionApply the rule once
The assignment stores 10.0 × 0.5 + 1.0 = 6.0.
State the Same Rule over the Whole Array
NumPy can apply the same arithmetic at every position:
array_calibrated = raw * 0.5 + 1.0
The multiplication produces one value for every position in raw, and the
addition then increases every one of those values. The expression preserves
shape (3, 2) and the (observations, sensors) axis meanings.
The loop and array forms describe the same six calculations at different levels of detail. The loop makes position-by-position execution visible. The array expression makes the uniform rule visible. Neither form is correct just because it runs.
For this calibration, every expected result is exact, so compare the arrays
with np.array_equal:
print(np.array_equal(loop_calibrated, array_calibrated))
True
np.array_equal requires the same shape and exactly equal values. That is the
claim we want for these results. It does not prove that the calibration rule
was the intended one: both implementations could repeat the same mistaken
formula. The hand checks at [1, 0] and [2, 1] still matter.
Q2. Choose an equality check
Which check best states that two integer count arrays must have the same shape and exactly the same values?
Select one choice, then check.
HintMatch the check to the claim
These are exact integer counts, not floating-point results that may differ by a tiny rounding amount.
SolutionUse exact array equality
Use np.array_equal(reference, result). It checks the full shape and every
value rather than one selected position.
Use a Tolerance for Floating-Point Results
Centering uses a reduction and subtraction:
We can write a loop reference that uses those same per-sensor means:
Both forms produce
[[-1. -2.]
[ 0. 0.]
[ 1. 2.]]
For these particular values, the arrays are exactly equal. Centering other
floating-point inputs may leave tiny differences when equivalent calculations
group operations differently. When the contract allows such small numerical
differences, use np.allclose:
True
The choice between the two checks belongs to the result contract:
| Required relationship | Check |
|---|---|
| same shape and exactly equal values | np.array_equal |
| corresponding floating-point values within a permitted tolerance | np.allclose |
Neither check supplies axis meaning. Keep the expected shape and axis names in the test or nearby explanation, and check at least one value independently.
Keep a Loop When the Steps Differ
A whole-array expression is clearest when one rule applies uniformly across the data. A loop can be clearer when each iteration updates running state, stops early, follows a substantial branch, or needs a step-by-step trace. We do not replace a readable loop merely to make the program shorter.
For example, a loop that reads values until an invalid record appears has an order and a stopping point. Hiding that control flow inside several compact operations would make the behavior harder to inspect. Choose the form that states the computation and its checks most clearly.
Q3. Compare loop and array centering
Complete both implementations, then use a tolerance-aware check to compare their floating-point results.
Editable Python
Ready to run.
HintImplement the same subtraction twice
Inside the loop, subtract sensor_means[sensor]. In the whole-array form,
subtract sensor_means from calibrated. Then compare the two arrays with
np.allclose.
SolutionCheck equivalent centered results
Both results have shape (3, 2) and values
[[-1, -2], [0, 0], [1, 2]]. The explicit shape check and np.allclose
state the two parts of the intended equivalence.
A loop reference and a whole-array expression can state the same numerical
work at different levels of detail. Use np.array_equal for an exact array
contract and np.allclose when floating-point tolerance is part of the
contract. Keep the loop when its order, state, branches, or trace make the
computation clearer. The next lesson combines each centered row with one
weight per sensor.