Typorithm · medium

Stacking features and computing a matrix product

pythonnumpynumerical-computingindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

Stacking features and computing a matrix product

0%

Concept and contract

Construct aligned feature columns and distinguish a matrix-vector product from elementwise multiplication.

Combining arrays requires an axis decision. concatenate joins along an existing axis, stack inserts a new axis, and column_stack turns aligned one-dimensional vectors into feature columns. These operations are not interchangeable merely because they accept several arrays. This lesson builds two feature columns with one row per observation, then computes a weighted combination with a matrix-vector product.

The two input vectors must refer to the same observations in the same order. Equal lengths establish a shape condition, not a source-identity guarantee. In a real pipeline, reconcile identifiers before constructing the feature matrix. The synthetic fixtures already have that alignment so the learner can concentrate on the numerical operation.

Mechanism and worked example

The worked function uses column_stack((first, second)) to construct a matrix shaped (observations, 2).

The worked function uses column_stack((first, second)) to construct a matrix shaped (observations, 2). A weight vector shaped (2,) then produces one value per observation through features @ weights. Trace one output as first[i] * weights[0] plus second[i] * weights[1]. This is different from features * weights, which broadcasts weights but retains one product per feature.

A matrix product can combine known coefficients without fitting a machine-learning model. The weights here are supplied synthetic values, not learned estimates or validated hiring predictions. Later ML lessons will discuss how coefficients are selected and evaluated; this array lesson establishes their shape and alignment first.

Complete worked example

python

import numpy as np

def inspect_example(first, second, weights):
    x = np.asarray(first, dtype=np.float64)
    y = np.asarray(second, dtype=np.float64)
    coefficients = np.asarray(weights, dtype=np.float64)
    if x.ndim != 1 or x.shape != y.shape or coefficients.shape != (2,):
        raise ValueError("expected two aligned feature vectors and two weights")
    if not all(np.isfinite(a).all() for a in (x, y, coefficients)):
        raise ValueError("expected finite numerical inputs")
    features = np.column_stack((x, y))
    return features @ coefficients
Reasoning
The worked function uses column_stack((first, second)) to construct a matrix shaped (observations, 2). A weight vector shaped (2,) then produces one value per observation through features @ weights. Trace one output as first[i] * weights[0] plus second[i] * weights[1]. This is different from features * weights, which broadcasts weights but retains one product per feature. A matrix product can combine known coefficients without fitting a machine-learning model. The weights here are supplied synthetic values, not learned estimates or validated hiring predictions. Later ML lessons will discuss how coefficients are selected and evaluated; this array lesson establishes their shape and alignment first.
Open in local Python playground ↗

Focused decision: context is in the complete example

python

features = np.column_stack((x, y))
result = features @ coefficients
Focused decision
Type this short numerical decision after reading its complete context. The complete imports, array construction, validation, and result checks remain in the worked example. Typing records practice; only the downloadable computer lab executes Python.

Counterexamples and common mistakes

The controlled counterexample uses elementwise multiplication and returns a matrix instead of an observation-level vector.

The controlled counterexample uses elementwise multiplication and returns a matrix instead of an observation-level vector. Summing the wrong axis afterwards could introduce a second population error. Another mistake is stacking the two feature vectors as rows and forgetting to update the multiplication contract. Rectangular examples make those errors visible when a square example might appear to work.

Joining observation batches is a different operation: concatenate along the row axis only after confirming identical feature meaning and column order. Adding a new source as another feature column would not preserve the same observations. State what each axis means before selecting a convenient stacking function.

Controlled mistake: inspect the failing numerical contract

python

import numpy as np

def inspect_example(first, second, weights):
    x = np.asarray(first, dtype=np.float64)
    y = np.asarray(second, dtype=np.float64)
    coefficients = np.asarray(weights, dtype=np.float64)
    if x.ndim != 1 or x.shape != y.shape or coefficients.shape != (2,):
        raise ValueError("expected two aligned feature vectors and two weights")
    if not all(np.isfinite(a).all() for a in (x, y, coefficients)):
        raise ValueError("expected finite numerical inputs")
    features = np.column_stack((x, y))
    return features * coefficients
Reasoning
The controlled counterexample uses elementwise multiplication and returns a matrix instead of an observation-level vector. Summing the wrong axis afterwards could introduce a second population error. Another mistake is stacking the two feature vectors as rows and forgetting to update the multiplication contract. Rectangular examples make those errors visible when a square example might appear to work. Joining observation batches is a different operation: concatenate along the row axis only after confirming identical feature meaning and column order. Adding a new source as another feature column would not preserve the same observations. State what each axis means before selecting a convenient stacking function.
Open in local Python playground ↗

Independent practice

Add a leading constant feature equal to one and accept three weights: intercept, first-feature coefficient and second-feature coefficient.

Add a leading constant feature equal to one and accept three weights: intercept, first-feature coefficient and second-feature coefficient. Keep the remaining validation and the matrix-vector product. This changes both the constructed column count and the expected weight length; the two boundaries must agree.

Predict the result when both feature values are zero and the intercept weight is five. The result should be five, which makes a missing intercept column observable. Do not append an extra observation row or add the intercept to the weight vector after multiplication.

Step 1: Add a leading constant feature and accept its intercept as the first of three weights. Step 2: Retain the working imports, input validation and array shapes. Change the stated policy, run the supplied practice cases, then explain the newly accepted or rejected boundary.

Practice starter: solve before reading the solution

python

import numpy as np

def inspect_example(first, second, weights):
    x = np.asarray(first, dtype=np.float64)
    y = np.asarray(second, dtype=np.float64)
    coefficients = np.asarray(weights, dtype=np.float64)
    if x.ndim != 1 or x.shape != y.shape or coefficients.shape != (2,):
        raise ValueError("expected two aligned feature vectors and two weights")
    if not all(np.isfinite(a).all() for a in (x, y, coefficients)):
        raise ValueError("expected finite numerical inputs")
    features = np.column_stack((x, y))
    return features @ coefficients

# Independent task: Add a leading constant feature and accept its intercept as the first of three weights.
Reasoning
Add a leading constant feature and accept its intercept as the first of three weights.
Open in local Python playground ↗
  • Hint 1: A leading constant feature is np.ones(x.size).
  • Hint 2: Validate shape (3,) and column-stack (np.ones(x.size), x, y).

Solution, tests and trade-offs

The solution column-stacks ones with the two feature vectors and validates a three-element weight vector.

The solution column-stacks ones with the two feature vectors and validates a three-element weight vector. The product still returns one float64 value per observation, including an empty result for empty aligned feature vectors. Tests include a zero-feature row, unequal vector lengths and a wrong weight count. These cases reject shape-compatible but semantically incorrect constructions.

A constant feature introduces no learning by itself. It is a representation that lets a matrix-vector product express an affine combination. Matrix conditioning, least-squares fitting and solving linear systems are valuable later topics; using an explicit inverse is not required for this small interface.

Practice solution and acceptance checks

python

import numpy as np

def inspect_example(first, second, weights):
    x = np.asarray(first, dtype=np.float64)
    y = np.asarray(second, dtype=np.float64)
    coefficients = np.asarray(weights, dtype=np.float64)
    if x.ndim != 1 or x.shape != y.shape or coefficients.shape != (3,):
        raise ValueError("expected two aligned feature vectors and three weights")
    if not all(np.isfinite(a).all() for a in (x, y, coefficients)):
        raise ValueError("expected finite numerical inputs")
    features = np.column_stack((np.ones(x.size), x, y))
    return features @ coefficients
Reasoning
The solution column-stacks ones with the two feature vectors and validates a three-element weight vector. The product still returns one float64 value per observation, including an empty result for empty aligned feature vectors. Tests include a zero-feature row, unequal vector lengths and a wrong weight count. These cases reject shape-compatible but semantically incorrect constructions. A constant feature introduces no learning by itself. It is a representation that lets a matrix-vector product express an affine combination. Matrix conditioning, least-squares fitting and solving linear systems are valuable later topics; using an explicit inverse is not required for this small interface.
Open in local Python playground ↗

Interview reasoning and next step

Explain concatenate, stack and column_stack with their resulting shapes, then compare elementwise multiplication with @.

Explain concatenate, stack and column_stack with their resulting shapes, then compare elementwise multiplication with @. Show exactly which coordinate is summed in the product. Describe how a leading column of ones represents an intercept and which validation must change when that column is added.

Type the compact feature construction and product on the PC, then recall the changed shape contract. The app questions use concrete weighted rows. Next, create a reproducible local random generator without changing unrelated random state in the process.

Optional stretch — after the core task works: Add one independently reasoned boundary case and explain its expected value before running it.

Computer practice: https://applydjinn.com/typorithm/numpy-lab-20261106.zip. Install pinned dependencies in an isolated Python environment. Run verify.py, then change the working exercise baseline and run --practice np-combining. The real NumPy arrays, numerical contracts, random state checks and temporary numeric files use owned fixtures only. No production database, feed, account or paid service is used. This lab executes Python; the PC typing trainer and native reading progress do not execute it.

Construct aligned feature columns and distinguish a matrix-vector product from elementwise multiplication.