Preparing the Arrays We Need
Botie needs a place for tomorrow's readings and a set of times at which to collect them. We can describe those arrangements directly instead of typing every repeated value ourselves.
10 sections · 4 questions · 2 coding challenges
The arrow keys move between sections too.
When the Layout Was Known Before the Measurements
BOTIE
NumPy's array-creation routines make those intentions explicit. A shape describes the arrangement; a fill value or spacing rule describes its initial contents. Our greenhouse schedule is an invented example of that distinction.
Sources for this history
Do We Have to Type Every Entry?
Suppose Botie plans to check three greenhouses on two mornings. We know how many entries the report will need before we know the temperatures. We also want a regular schedule of checks. Neither task should require copying the same number over and over.
NumPy can create arrays from a shape, a repeated value, or a sequence rule. The choice matters: an empty place in a report is not evidence that the thermometer measured zero.
Decide what a row means
Each row belongs to a morning and each column to a greenhouse.
Monday
- north
- middle
- south
Tuesday
- north
- middle
- south
What we can now calculate
The shape comes from the requested report. The filled sheet supplies references, while subtraction compares them with actual observations.
Explore the full example
Choose an example, then change a value. Follow the calculation below to see which result changes and why. These are small teaching examples; the construction later asks you to choose the operations yourself.
BOTIE
Result from these values
| 8 | 2 | -4 |
| 6 | -2 | -16 |
Follow the operations
1. Number of days
2
2. Number of greenhouses
3
3. Target temperature
20
4. Fill a rectangular sheet
20 20 20 20 20 20 5. Recorded temperatures
12 18 24 14 22 36 6. Subtract
8 2 -4 6 -2 -16 7. Result
8 2 -4 6 -2 -16
The workshop uses small positive dimensions. It does not expose uninitialised storage. Editing this example does not change the workshop tests.
1. Start With a Shape and a Meaning
For a report with two mornings and three greenhouses, we need two rows and three columns. The shape is a tuple, passed as one argument. zeros fills an array with zeros; ones fills it with ones; full uses a value we supply.
A zero-filled array is useful for a counter before any events have occurred. A constant target table is useful for a shared rule. Neither is a table of observations merely because it has the right shape.
Create counts and targets separately
We specify integer storage for counts and floating-point storage for temperatures. The zeros and full functions allocate new arrays.
import numpy as np
checks = np.zeros((2, 3), dtype=int)
targets = np.full((2, 3), 20.0)
print(checks.tolist())
print(targets.tolist())
print(np.ones(3, dtype=int).tolist())[[0, 0, 0], [0, 0, 0]]
[[20.0, 20.0, 20.0], [20.0, 20.0, 20.0]]
[1, 1, 1]The arrays have deliberate initial values. NumPy also offers empty, which leaves numerical contents uninitialised. Those contents must be written before reading them; empty does not mean a safe table of zeros.
2. Reuse a Layout Without Guessing Its Size
Suppose the number of greenhouses changes. Hard-coding three columns in every calculation invites mistakes. The functions ending in _like can take their shape from an existing array. Their default dtype also follows that array, so override it when the new meaning needs a different type.
Make a counter that matches the incoming report
Here zeros_like gives each observed position a corresponding counter, and full_like creates a target table with the same layout.
import numpy as np
readings = np.array([[12., 18., 24.], [14., 22., 36.]])
counts = np.zeros_like(readings, dtype=int)
targets = np.full_like(readings, 20.0)
print(counts.shape)
print(counts.tolist())
print(targets.tolist())(2, 3)
[[0, 0, 0], [0, 0, 0]]
[[20.0, 20.0, 20.0], [20.0, 20.0, 20.0]]The layout now follows the data. ones_like provides the corresponding all-ones array when every position starts with one contribution.
3. Choose a Step or Choose a Count
A schedule may specify a time interval, while a graph may specify how many points to draw between two limits. Those are different requests. arange uses a step and excludes the stopping boundary. linspace uses a count and includes both endpoints by default.
For fractional spacings, linspace is often clearer when the intended count matters. Floating-point steps in arange can make boundary behaviour surprising.
Make an inspection schedule and a trial grid
The first call starts at six, stops before fourteen, and advances by two. The second requests five equally spaced trial settings including zero and one.
import numpy as np
hours = np.arange(6, 14, 2)
settings = np.linspace(0, 1, 5)
print(hours.tolist())
print(settings.tolist())[6, 8, 10, 12]
[0.0, 0.25, 0.5, 0.75, 1.0]The final argument has a different meaning in these two functions. Treating the count in linspace as a step would give the wrong experiment.
4. Preserve a Measurement When No Change Is Intended
Later we will use matrices to combine measurements. We also need a matrix that expresses leaving each measurement alone. An identity matrix has ones on its diagonal and zeros elsewhere, so each output keeps its matching input and ignores the others.
Create the identity pattern
eye creates this pattern. With three inputs, we request a three-by-three matrix. The matrix-calculation lesson will show how it acts on readings.
import numpy as np
identity = np.eye(3, dtype=int)
print(identity.tolist())
print(identity.shape)[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
(3, 3)This is a rule we constructed, not a matrix fitted from data. Keep that distinction when using initial arrays in later model exercises.
Check yourself
Questions on Parts 1 to 4
Question 1 of 4
What shape does this allocation request?
Use this setup. The code is given; its result is for you to work out.
import numpy as np
counts = np.zeros((2, 3), dtype=int)Try it with Botie
Build with Botie
Write and run Python