Lab 05 — NumPy I: Arrays, Creation, Indexing, dtypes¶
Session: Week 3 · Session 5 · 90 min CLO: CLO-1 Difficulty: Beginner
Learning objectives¶
By the end of this lab you can:
- Create
ndarrays withnp.array,np.arange,np.zeros,np.ones,np.linspace,np.full. - Inspect
shape,ndim,dtype, andsize. - Index and slice 1-D and 2-D arrays (rows, columns, steps).
- Explain why arrays are faster than lists and why a single dtype matters.
Problem statement¶
A retail chain records daily footfall (visitors per hour) across three
stores for one day: 24 hourly readings per store, stored as a 2-D array of
shape (3, 24). Using only NumPy, you must: build the array, pull specific
hours, compute per-store and per-hour summaries, and prove you can slice
without copying mistakes.
Dataset requirements¶
Generate the data inline with np.random using a fixed seed, so every run
is identical. No files.
Step-by-step tasks¶
- Generate the array:
np.random.seed(7), thenfootfall = np.random.randint(0, 60, size=(3, 24)). Print shape, ndim, dtype, size — explain each in a comment. - Slice the morning (hours 8–11, columns 8:12) for all stores. Print it.
- Extract Store 2's entire day (row index 1). What is its shape after
slicing — and why is it not
(1, 24)? Fix it withreshape(1, -1)and compare. - Per-store totals with
sum(axis=1)— write in a comment which axis sums away and why. - Per-hour mean across stores with
mean(axis=0). - Busiest hour: find the hour (column) with the highest total across
stores using
argmaxon the column sums. - Convert the array to
float64, add 0.5, and confirm the dtype changed. Explain why mixed types in one array are impossible.
Starter code¶
import numpy as np
np.random.seed(7)
footfall = np.random.randint(0, 60, size=(3, 24))
print("shape:", footfall.shape)
print("ndim:", footfall.ndim)
print("dtype:", footfall.dtype)
print("size:", footfall.size)
# your code here for tasks 2-7
Expected output¶
shape: (3, 24),ndim: 2,dtype: int64,size: 72.- Morning slice: a
(3, 4)block of integers. - Store 2's day: a 1-D array of 24 ints; after reshape
(1, 24). - Per-store totals: three numbers summing to the same as
footfall.sum(). - Per-hour means: 24 floats.
- Busiest hour: an integer hour index (0–23) — with a fixed seed this is
deterministic; your answer must match
np.argmax(footfall.sum(axis=0)).
Questions¶
- What does
axis=0mean insum(axis=0)?axis=1? - Why does slicing a single row give a 1-D array? How do you keep it 2-D?
- What is
dtype, and why must all elements share one? footfall[1, 8:12]vsfootfall[1][8:12]— same result? Explain.- Why use
np.random.seed(7)in a lab?
Challenge task¶
Create a masked comparison without where: produce a boolean array
busy = footfall > 40, count how many hours each store was "busy"
(busy.sum(axis=1)), and report which store had the most busy hours.
Then explain in one comment why busy is bool dtype and what that means
for sum.
Marking rubric¶
| Criteria | Max | Notes |
|---|---|---|
| Array created + attributes explained | 3 | shape/ndim/dtype/size correct |
| Morning slice correct | 2 | (3, 4) block |
| Row slice + reshape reasoning | 3 | shape explained, reshape used |
| Axis sums correct & commented | 3 | totals match footfall.sum() |
| Hour mean + busiest hour via argmax | 3 | matches seeded expectation |
| dtype conversion task | 2 | float64 confirmed |
| Answers to questions | 2 | Q1, Q4 correct |
| Challenge: busy-hours mask | 3 | boolean mask + counts + store id |
| Total | 21 |