Introduction¶

In this notebook we'll learn how to use NumPy to work with numerical data.

No description has been provided for this image

Import Statements¶

/var/folders/3r/l53_rt4d2rv_ry5lhbkpdmk00000gn/T/ipykernel_60536/881172702.py:4: DeprecationWarning: scipy.misc is deprecated and will be removed in 2.0.0
  from scipy import misc # contains an image of a racoon!

Understanding NumPy's ndarray¶

NumPy's most amazing feature is the powerful ndarray.

No description has been provided for this image

1-Dimensional Arrays (Vectors)¶

My array: [1.1 9.2 8.1 4.7]
Array shape: (4,)
Element at index 2: 8.1
Number of dimensions: 1

2-Dimensional Arrays (Matrices)¶

Element at row 1, column 2: 7
Row 1: [5 6 7 8]
array_2d has 2 dimensions
Its shape is (2, 4)
It has 2 rows and 4 columns
[[1 2 3 9]
 [5 6 7 8]]

N-Dimensional Arrays (Tensors)¶

Exploring a 3D array to determine its shape, index a specific value (18), retrieve a 1D vector [97, 0, 27, 18], and extract a (3, 2) submatrix — all using standard index and slice syntax.

We have 3 dimensions
Its shape is (3, 2, 4)

axis 0 has 3 elements
axis 1 has 2 elements
axis 2 has 4 elements
Element at [2, 1, 3]: 18
1D vector at [2, 1, :]:
[97  0 27 18]

Array Generation and Slicing Operations¶

Generating a Range Vector with np.arange()¶

[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]

Slicing and Subsetting 1D Arrays¶

Last 3 values: [27 28 29]
Fourth to sixth values: [13 14 15]
All except first 12: [22 23 24 25 26 27 28 29]
Every second value: [10 12 14 16 18 20 22 24 26 28]

Reversing Array Order¶

Reversed array:
[29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10]
Reversed array using np.flip:
[29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10]

Finding Non-Zero Indices with np.nonzero()¶

array b: [6 0 9 0 0 5 0]
Non-zero indices in b: (array([0, 2, 5]),)

Generating a Random 3D Array¶

3D array z:
[[[0.14156158 0.87700025 0.96787689]
  [0.061531   0.60855304 0.43806378]
  [0.10833965 0.27409845 0.88006431]]

 [[0.04050787 0.39174103 0.39807861]
  [0.41987716 0.87660479 0.33141227]
  [0.69324824 0.01232195 0.80558047]]

 [[0.29503859 0.19712683 0.18492926]
  [0.88943561 0.31470241 0.0637483 ]
  [0.20303319 0.45315313 0.52456203]]]
Shape of z: (3, 3, 3)

Creating an Evenly Spaced Vector with np.linspace()¶

[  0.   12.5  25.   37.5  50.   62.5  75.   87.5 100. ]
(9,)

Plotting Linspace Vectors as a Line Chart¶

No description has been provided for this image

Visualising a Random Array as an Image¶

(128, 128, 3)
No description has been provided for this image

Linear Algebra with Vectors¶

array([ 6,  6,  5, 10])
array([ 8,  5,  6, 21])
[4, 5, 2, 7, 2, 1, 3, 3]

Broadcasting and Scalars¶

array([10, 20, 12, 34, 40])
array([[11, 12, 13, 14],
       [15, 16, 17, 18]])
array([[ 5, 10, 15, 20],
       [25, 30, 35, 40]])

Matrix Multiplication with @ and .matmul()¶

No description has been provided for this image
(4, 2): a has 4 rows and 2 columns.
(2, 3): b has 2 rows and 3 columns.
Dimensions of result: (4x2)*(2x3)=(4x3)

Verifying Matrix Multiplication with @ and np.matmul()¶

array([[19, 25, 18],
       [ 5,  8,  5],
       [34, 22, 28],
       [71, 65, 62]])
array([[19, 25, 18],
       [ 5,  8,  5],
       [34, 22, 28],
       [71, 65, 62]])

Manipulating Images as ndarrays¶

Downloading file 'face.dat' from 'https://raw.githubusercontent.com/scipy/dataset-face/main/face.dat' to '/Users/xavieroconcapdeville/Library/Caches/scipy-data'.
(np.float64(-0.5), np.float64(1023.5), np.float64(767.5), np.float64(-0.5))
No description has been provided for this image

Inspecting the Raccoon Image Array¶

Image type: <class 'numpy.ndarray'>
Image shape: (768, 1024, 3)
Image dimensions: 3


height: 768 pixels
width: 1024 pixels
color channels: 3

Converting an RGB Image to Greyscale via Luminance Dot Product¶

<matplotlib.image.AxesImage at 0x1149fe690>
No description has been provided for this image

Spatial and Pixel Transforms: Flip, Rotate, and Invert¶

Solutions¶

<matplotlib.image.AxesImage at 0x1206d9a30>
No description has been provided for this image
<matplotlib.image.AxesImage at 0x120450f20>
No description has been provided for this image
<matplotlib.image.AxesImage at 0x12695de80>
No description has been provided for this image

Use your Own Image!¶

Use PIL to open¶

<matplotlib.image.AxesImage at 0x12699db50>
No description has been provided for this image
Image type: <class 'numpy.ndarray'>
Image shape: (533, 799, 3)
Image dimensions: 3


height: 533 pixels
width: 799 pixels
color channels: 3
<matplotlib.image.AxesImage at 0x126a5e210>
No description has been provided for this image

Key Findings¶

  • A colour image is a rank-3 tensor of shape (H, W, 3) — every pixel is three uint8 integers
  • The raccoon image is 768 × 1024 px (786,432 pixels total across 3 channels = 2,359,296 values)
  • The macaron photograph is 533 × 799 px (426,267 pixels total)
  • Greyscale conversion via the ITU-R BT.709 luminance dot product (@ [0.2126, 0.7152, 0.0722]) collapses (768, 1024, 3) → (768, 1024) in a single operation
  • Broadcasting enables scalar operations (255 - img, img / 255) to transform all pixel values simultaneously without loops
  • np.linspace(0, 100, 9) produces [0.0, 12.5, 25.0, 37.5, 50.0, 62.5, 75.0, 87.5, 100.0] — 9 evenly spaced values including both endpoints
  • Matrix multiplication (4×2) @ (2×3) produces a (4×3) result; verified computationally with np.matmul() and the @ operator giving identical output
  • np.flip() reverses axis 0 (rows), flipping the image upside down; np.rot90() rotates 90° counter-clockwise — both return views, not copies
  • Colour inversion (255 - img) maps black (0) to white (255) and vice versa, equivalent to a photographic solarisation effect