Matrices: The Grid That Holds Your Entire Dataset

dev.to

Open any spreadsheet you have ever worked with.

Rows of data. Columns of features. Every cell a number.

That spreadsheet is a matrix.

Not metaphorically. Not approximately. When you load that spreadsheet into Python for machine learning, it becomes a NumPy matrix, number for number, row for row. The thing you have been looking at in Excel your whole life is the exact data structure that powers AI.


From Vector to Matrix

A vector is one row of numbers.

import numpy as np

student = np.array([85, 92, 78, 88])   # four exam scores
Enter fullscreen mode Exit fullscreen mode

A matrix is multiple rows stacked together.

students = np.array([
    [85, 92, 78, 88],   # student 1
    [91, 76, 83, 95],   # student 2
    [67, 88, 72, 79],   # student 3
    [94, 85, 90, 91]    # student 4
])

print(students)
print(students.shape)
Enter fullscreen mode Exit fullscreen mode

Output:

[[85 92 78 88]
 [91 76 83 95]
 [67 88 72 79]
 [94 85 90 91]]

(4, 4)
Enter fullscreen mode Exit fullscreen mode

Shape (4, 4) means 4 rows and 4 columns. Four students. Four exams. Every data point in its place.

This is a dataset. This is how your machine learning model sees your data before it ever touches an algorithm.


Shape Is Everything

In AI code, the first thing you check about any matrix is its shape.

data = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print(data.shape)    # (2, 3)
print(data.ndim)     # 2 dimensions
print(data.size)     # 6 total elements
Enter fullscreen mode Exit fullscreen mode

Output:

(2, 3)
2
6
Enter fullscreen mode Exit fullscreen mode

The convention is always (rows, columns). A shape of (1000, 28) means 1000 rows of data with 28 features each. In deep learning you will check .shape constantly. Wrong shapes cause most errors. Get comfortable reading them.


Accessing Elements

Getting a single element needs both row and column index.

students = np.array([
    [85, 92, 78, 88],
    [91, 76, 83, 95],
    [67, 88, 72, 79],
    [94, 85, 90, 91]
])

print(students[0, 0])    # first row, first column: 85
print(students[2, 1])    # third row, second column: 88
print(students[1, :])    # entire second row
print(students[:, 2])    # entire third column
Enter fullscreen mode Exit fullscreen mode

Output:

85
88
[91 76 83 95]
[78 83 72 90]
Enter fullscreen mode Exit fullscreen mode

students[1, :] means: row 1, all columns. The : means everything.

students[:, 2] means: all rows, column 2. That is every student's score on the third exam.

This slicing syntax is how you pull out specific features or specific records from your entire dataset. You will do this hundreds of times.


Creating Matrices You Actually Need

Three matrix creation patterns come up constantly in AI.

zeros = np.zeros((3, 4))
print(zeros)
Enter fullscreen mode Exit fullscreen mode

Output:

[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]
Enter fullscreen mode Exit fullscreen mode

Start with a matrix of zeros and fill it in. Used for initializing weight matrices in neural networks.

identity = np.eye(4)
print(identity)
Enter fullscreen mode Exit fullscreen mode

Output:

[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
Enter fullscreen mode Exit fullscreen mode

Ones on the diagonal, zeros everywhere else. The identity matrix. Multiplying any matrix by the identity gives you the original matrix back. The matrix equivalent of multiplying by 1. Comes up constantly in linear algebra operations.

random = np.random.randn(3, 4)
print(random)
Enter fullscreen mode Exit fullscreen mode

Output:

[[ 0.4832 -1.2341  0.7823  0.1029]
 [-0.5541  1.3021 -0.2109  0.8834]
 [ 0.2341 -0.9821  0.4521 -1.1023]]
Enter fullscreen mode Exit fullscreen mode

Random values from a normal distribution. Used to initialize neural network weights. Why random? Because if all weights started at the same value, every neuron in a layer would learn the same thing. Random initialization breaks that symmetry.


Transpose: Flipping Rows and Columns

Transposing a matrix turns its rows into columns and its columns into rows.

a = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

print("Original shape:", a.shape)
print(a)

print("\nTransposed shape:", a.T.shape)
print(a.T)
Enter fullscreen mode Exit fullscreen mode

Output:

Original shape: (2, 3)
[[1 2 3]
 [4 5 6]]

Transposed shape: (3, 2)
[[1 4]
 [2 5]
 [3 6]]
Enter fullscreen mode Exit fullscreen mode

A (2, 3) matrix becomes a (3, 2) matrix. Row 1 [1, 2, 3] became column 1. Row 2 [4, 5, 6] became column 2.

Transpose shows up constantly in neural network math. When shapes do not align for matrix multiplication, transposing one of them often fixes it. You will develop an instinct for when to use .T very quickly.


Math Operations on Matrices

Element-wise operations work exactly like vectors.

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

print(a + b)
print(a * b)
print(a * 2)
Enter fullscreen mode Exit fullscreen mode

Output:

[[ 6  8]
 [10 12]]

[[ 5 12]
 [21 32]]

[[2 4]
 [6 8]]
Enter fullscreen mode Exit fullscreen mode

Each element matched with its counterpart. Added, multiplied, scaled. No loops. NumPy handles all 10 million elements simultaneously if needed.


Reshaping: Same Data, Different Shape

One of the most common operations in deep learning is reshaping. Same numbers, different arrangement.

flat = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

matrix = flat.reshape(3, 4)
print(matrix)
print(matrix.shape)
Enter fullscreen mode Exit fullscreen mode

Output:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

(3, 4)
Enter fullscreen mode Exit fullscreen mode

12 numbers arranged as a single row became 3 rows of 4. Total elements unchanged. Shape changed.

Use -1 when you want NumPy to figure out one dimension automatically.

matrix = flat.reshape(-1, 4)    # "however many rows needed, 4 columns"
print(matrix.shape)             # (3, 4)

matrix = flat.reshape(2, -1)    # "2 rows, however many columns needed"
print(matrix.shape)             # (2, 6)
Enter fullscreen mode Exit fullscreen mode

Images use this constantly. A 28x28 pixel image stored as a flat vector of 784 numbers needs to be reshaped to (28, 28) for convolutional networks or kept flat for fully connected ones. Reshape is the tool.


Aggregations Across Rows and Columns

Getting summaries across different axes.

scores = np.array([
    [85, 92, 78],    # student 1
    [91, 76, 83],    # student 2
    [67, 88, 72]     # student 3
])

print(np.mean(scores))          # mean of all values
print(np.mean(scores, axis=0))  # mean of each column (each exam)
print(np.mean(scores, axis=1))  # mean of each row (each student)
Enter fullscreen mode Exit fullscreen mode

Output:

81.0
[81.         85.33333333 77.66666667]
[85.         83.33333333 75.66666667]
Enter fullscreen mode Exit fullscreen mode

axis=0 collapses the rows, giving you one value per column.
axis=1 collapses the columns, giving you one value per row.

This axis concept trips people up. Think of it as: axis=0 moves down the rows. axis=1 moves across the columns. In neural networks you will use axis operations to normalize data, calculate losses, and aggregate predictions.


A Real Dataset as a Matrix

Putting it all together with something concrete.

import numpy as np

data = np.array([
    [23, 50000, 1, 0],
    [35, 80000, 0, 1],
    [28, 62000, 1, 1],
    [45, 95000, 0, 1],
    [31, 71000, 1, 0]
])

print(f"Dataset shape: {data.shape}")
print(f"Number of samples: {data.shape[0]}")
print(f"Number of features: {data.shape[1]}")

ages   = data[:, 0]
income = data[:, 1]

print(f"\nAge range: {ages.min()} to {ages.max()}")
print(f"Average income: {income.mean():.0f}")
print(f"\nFirst 3 records:\n{data[:3]}")
Enter fullscreen mode Exit fullscreen mode

Output:

Dataset shape: (5, 4)
Number of samples: 5
Number of features: 4

Age range: 23 to 45
Average income: 71600

First 3 records:
[[23 50000      1      0]
 [35 80000      0      1]
 [28 62000      1      1]]
Enter fullscreen mode Exit fullscreen mode

Five people. Four features each. Select any column as a feature vector. Select any row as a data point. Compute statistics across the whole thing. This is exactly what happens when you load a CSV and pass it to a machine learning model.


Try This

Create matrices_practice.py.

Build a matrix representing a small image. Create a (5, 5) NumPy array filled with values between 0 and 255 representing pixel brightness. Use np.random.randint(0, 256, size=(5, 5)).

Then do all of this:

Print the shape and total number of pixels.

Get the pixel value at row 2, column 3.

Get the entire middle row (row 2).

Calculate the average brightness of the whole image.

Calculate the average brightness of each row.

Flatten it to a 1D vector using .reshape(-1) and print its shape.

Transpose it and print the result.

Normalize the pixel values to be between 0 and 1 by dividing the entire matrix by 255. This is called normalization and you will do it to every image before feeding it to a neural network.


What's Next

You know how to organize data into matrices. Now the question is what do you actually do with them.

The next post is the dot product. A specific way of multiplying vectors together that produces one number representing similarity. It is the single most important operation in all of deep learning and you are two posts away from fully understanding it.

Source: dev.to

arrow_back Back to News