Python Tutorial › Libraries & Databases › NumPy

Python NumPy

IntermediateLesson 45 of 4714 min read11 runnable examples

NumPy is the foundation of numerical Python. Its ndarray stores numbers in a compact block of memory and runs maths on whole arrays at once, which is far faster and shorter than looping over lists. Pandas, scikit-learn and Matplotlib are all built on it.

Advertisement
In this lesson
  • Create arrays and inspect their shape
  • Index, slice and filter with masks
  • Vectorised maths and broadcasting
  • Statistics along rows and columns

Install and import

Terminal
python -m pip install numpy
Python
import numpy as npprint(np.__version__.split(".")[0] >= "2")
Output
True

np is the standard alias; every NumPy example you find online uses it.

Create arrays

Python
import numpy as np a = np.array([3, 1, 4, 1, 5])print(a, a.dtype, a.shape) m = np.array([[1, 2, 3], [4, 5, 6]])print(m)print(m.shape, m.ndim, m.size)
Output
[3 1 4 1 5] int64 (5,)
[[1 2 3]
 [4 5 6]]
(2, 3) 2 6

Helper functions build common arrays:

Python
import numpy as np print(np.zeros(3), np.ones((2, 2), dtype=int).tolist())print(np.arange(0, 10, 2))print(np.linspace(0, 1, 5))print(np.eye(3, dtype=int))
Output
[0. 0. 0.] [[1, 1], [1, 1]]
[0 2 4 6 8]
[0.   0.25 0.5  0.75 1.  ]
[[1 0 0]
 [0 1 0]
 [0 0 1]]

Arrays vs lists

Maths on an array applies to every element. The same operator on a list does something else:

Python
import numpy as np prices = [100, 250, 80]print(prices * 2)                 # list: repeated arr = np.array(prices)print(arr * 2)                    # array: every element doubledprint(arr * 1.18)                 # add 18% tax to allprint(arr + np.array([1, 2, 3]))  # element-wise addition
Output
[100, 250, 80, 100, 250, 80]
[200 500 160]
[118.  295.   94.4]
[101 252  83]

Reshape

Python
import numpy as np a = np.arange(1, 13)grid = a.reshape(3, 4)print(grid)print(grid.T.shape)               # transpose: 4 x 3print(grid.flatten()[:5])
Output
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
(4, 3)
[1 2 3 4 5]

Indexing and slicing

For 2-D arrays, use [row, column]:

Python
import numpy as np g = np.arange(1, 13).reshape(3, 4)print(g[0, 0], g[2, -1])print(g[1])            # second rowprint(g[:, 1])         # second columnprint(g[0:2, 1:3])     # sub-grid
Output
1 12
[5 6 7 8]
[ 2  6 10]
[[2 3]
 [6 7]]

Boolean masks

A comparison gives an array of True/False values, which you can use to select elements:

Python
import numpy as np scores = np.array([45, 82, 67, 91, 38, 74])mask = scores >= 60print(mask)print(scores[mask])print(scores[(scores > 50) & (scores < 80)])   # use & and |, not and/orprint(np.where(scores >= 60, "pass", "fail"))
Output
[False  True  True  True False  True]
[82 67 91 74]
[67 74]
['fail' 'pass' 'pass' 'pass' 'fail' 'pass']

Statistics

Python
import numpy as np sales = np.array([[120, 90, 150],                  [80, 110, 95]])       # 2 stores x 3 monthsprint(sales.sum(), sales.mean().round(2))print(sales.sum(axis=0))                # per month (down the columns)print(sales.sum(axis=1))                # per store (across the rows)print(sales.max(), sales.argmax(), np.median(sales))
Output
645 107.5
[200 200 245]
[360 285]
150 2 102.5
Tip

axis=0 means “collapse the rows” (one result per column) and axis=1 means “collapse the columns” (one result per row).

Broadcasting

When shapes differ, NumPy stretches the smaller array to fit, as long as the dimensions are compatible:

Python
import numpy as np marks = np.array([[70, 80, 90],                  [60, 75, 85]])bonus = np.array([5, 0, 10])            # one bonus per subjectprint(marks + bonus)print(marks / marks.max(axis=1, keepdims=True))   # normalise each row
Output
[[ 75  80 100]
 [ 65  75  95]]
[[0.77777778 0.88888889 1.        ]
 [0.70588235 0.88235294 1.        ]]

Random numbers

Python
import numpy as np rng = np.random.default_rng(seed=42)print(rng.integers(1, 7, size=5))         # dice rollsprint(rng.random(3).round(3))print(rng.choice(["red", "green", "blue"], size=4))
Output
[1 5 4 3 3]
[0.697 0.094 0.976]
['blue' 'blue' 'blue' 'blue']

A fixed seed makes the results repeatable, which is useful for tests.

Why NumPy is fast

Python
import numpy as np, time n = 1_000_000numbers = list(range(n))arr = np.arange(n) t = time.perf_counter(); total_list = sum(x * x for x in numbers); list_time = time.perf_counter() - tt = time.perf_counter(); total_np = int((arr * arr).sum()); np_time = time.perf_counter() - t print(total_list == total_np)print("NumPy faster:", np_time < list_time)
Output
True
NumPy faster: True

Check your understanding

Predict the output

import numpy as npa = np.array([[1, 2], [3, 4]])print(a * a, a.sum(axis=0), a[a > 2])

Quick quiz

1. What is np.array([1, 2, 3]) * 2?

2. What does arr.shape return for a 3 x 4 array?

3. Which combines two conditions in a mask?

Exercise: class report

Marks of 4 students in 3 subjects are in a 4 x 3 array. Print each student’s total, each subject’s average, and how many marks are below 40.

Input
[[78, 65, 90], [35, 48, 52], [88, 92, 79], [40, 39, 61]]
Expected output
Totals: [233 135 259 140]
Subject averages: [60.25 61.   70.5 ]
Marks below 40: 2
Hint 1

sum(axis=1) for students, mean(axis=0) for subjects.

Program Practice

NumPy FAQ

What is NumPy used for?

Fast numerical computing: arrays, linear algebra, statistics and random numbers. It is the base for pandas, SciPy, scikit-learn and most data and ML libraries.

What is the difference between a Python list and a NumPy array?

A NumPy array holds items of one type in contiguous memory and supports element-wise maths. A list can mix types and its operators mean concatenation and repetition.

What does axis=0 mean in NumPy?

It means “along the rows”, so the result has one value per column. axis=1 gives one value per row.

1 thought on “Python NumPy”

Leave a Comment