Python for Data course menu
NumPy Aggregations, axis and Random Numbers
Summarise NumPy arrays with sum, mean, median, std, min, max and percentile, understand the axis argument for rows and columns, find positions with argmax, and generate reproducible random numbers with default_rng.
On this page
Aggregations reduce many numbers to one: a total, an average, a maximum. NumPy has fast versions of all of them, and the axis argument lets you compute them per row or per column of a table.
Whole-array summaries#
import numpy as np
orders = np.array([250, 120, 560, 90, 310, 75, 430])
print(orders.sum(), orders.mean(), np.median(orders))
print(orders.min(), orders.max(), orders.max() - orders.min())
print(orders.std().round(2))
print(np.percentile(orders, [25, 50, 75]))
print(orders.argmax(), orders.argmin()) # positions of the max and min1835 262.14285714285717 250.0
75 560 485
170.79
[105. 250. 370.]
2 5The median (250) is lower than the mean (262.14…) because the big orders pull the mean up. Descriptive Statistics explains when to use which.
The axis argument#
For a 2D array, axis=0 collapses the rows (giving one result per column) and axis=1 collapses the columns (one result per row):
import numpy as np
# rows: three shops; columns: Mon..Thu sales
sales = np.array([
[12, 15, 11, 20],
[ 8, 22, 17, 13],
[19, 10, 14, 16],
])
print(sales.sum()) # everything
print(sales.sum(axis=0)) # per day (down each column)
print(sales.sum(axis=1)) # per shop (across each row)
print(sales.mean(axis=1).round(2))
print(sales.argmax(axis=1)) # best day for each shop177
[39 47 42 49]
[58 60 59]
[14.5 15. 14.75]
[3 1 0]A way to remember: the axis you name is the one that disappears. The result of axis=0 on a (3, 4) array has shape (4,).
Cumulative and counting functions#
import numpy as np
deposits = np.array([100, 50, 200, 75])
print(np.cumsum(deposits)) # running balance
print(np.diff(np.array([3, 7, 12, 20]))) # change between neighbours
colours = np.array(["red", "blue", "red", "green", "red"])
values, counts = np.unique(colours, return_counts=True)
print(values, counts)[100 150 350 425]
[4 5 8]
['blue' 'green' 'red'] [1 1 3]Missing values: NaN#
NumPy uses np.nan (not a number) for missing floats. Any aggregation that touches it returns nan, so use the nan-aware versions:
import numpy as np
ratings = np.array([4.5, np.nan, 3.0, 5.0])
print(ratings.mean())
print(np.nanmean(ratings), np.nansum(ratings), np.isnan(ratings).sum())nan
4.166666666666667 12.5 1pandas handles missing data more conveniently; see Missing Values.
Random numbers you can reproduce#
Simulations, sampling and machine learning need random numbers. Create a generator with np.random.default_rng. Giving it a seed makes the "random" numbers the same every run, so your results are reproducible:
import numpy as np
rng = np.random.default_rng(42)
print(rng.integers(1, 7, size=10)) # ten dice rolls (7 is excluded)
print(rng.random(3).round(3)) # floats in [0, 1)
print(rng.normal(loc=170, scale=8, size=4).round(1)) # heights around 170 cm
print(rng.choice(["heads", "tails"], size=5))
rng2 = np.random.default_rng(42)
print(rng2.integers(1, 7, size=10)) # same seed, same numbers[1 5 4 3 3 6 1 5 2 1]
[0.976 0.761 0.786]
[169.9 163.2 177. 176.2]
['tails' 'tails' 'heads' 'tails' 'tails']
[1 5 4 3 3 6 1 5 2 1]default_rng is the modern API. Older code uses np.random.seed(42) with functions like np.random.randint; it still works, but new code should use a generator.
Simulating with random numbers#
Estimate the probability that two dice add up to 7 by rolling 100,000 times:
import numpy as np
rng = np.random.default_rng(0)
rolls = rng.integers(1, 7, size=(100_000, 2))
sevens = (rolls.sum(axis=1) == 7).mean()
print(round(sevens, 4), round(6 / 36, 4))0.1678 0.1667The simulated value is close to the exact answer, 6/36. The mean of a boolean array is the fraction of True values, a handy trick.
Common mistakes#
Practice#
Practice exercise
Monthly revenue (in thousands) for two products over six months is [[12, 15, 14, 18, 21, 19], [9, 8, 11, 10, 12, 15]]. Print each product's total and average (rounded to 1 decimal), the month number (1–6) with the highest combined revenue, and the month-to-month change in combined revenue.
Show hint
sum(axis=1) and mean(axis=1) per product; sum(axis=0) gives combined revenue per month; argmax() + 1 turns a position into a month number; np.diff gives the changes.
Show solution
import numpy as np
revenue = np.array([[12, 15, 14, 18, 21, 19], [9, 8, 11, 10, 12, 15]])
print(revenue.sum(axis=1), revenue.mean(axis=1).round(1))
combined = revenue.sum(axis=0)
print(combined, "best month:", combined.argmax() + 1)
print(np.diff(combined))[99 65] [16.5 10.8]
[21 23 25 28 33 34] best month: 6
[2 2 3 5 1]Key takeaway#
Finished this lesson?