Put the Same Readings Into the Right Arrangement
A sensor may send one long sequence while a calculation expects rows. We need to change the arrangement without changing which measurements belong to each day and greenhouse.
10 sections · 4 questions · 2 coding challenges
The arrow keys move between sections too.
Separating Stored Order From the Shape of a Calculation
BOTIE
NumPy's manipulation routines describe shape and axis changes explicitly. This makes array-oriented calculations possible without treating every change of layout as a new measurement. The documented distinction between reshape, transpose, and joining is the mechanism we use here.
Sources for this history
Where Does One Day End and the Next Begin?
Botie's logger sends six readings in order: all three greenhouses on Monday, then all three on Tuesday. The message has no row breaks. We need to restore the table before asking for a daily or greenhouse summary.
Reshaping changes how existing entries are grouped. Transposing exchanges axes. Joining combines separate collections. These operations can produce similar-looking shapes while assigning very different meanings to their positions.
Read the logger's order
The first three values belong to Monday and the next three to Tuesday.
Sequence
- 10
- 20
- 30
- 14
- 22
- 36
What we can now calculate
Grouping restores the day boundaries. Transpose then follows greenhouse identity across those days.
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
| 10 | 14 |
| 20 | 22 |
| 30 | 36 |
Follow the operations
1. Flat logger sequence
- 010
- 120
- 230
- 314
- 422
- 536
2. Greenhouses per day
3
3. Group a sequence into rows
10 20 30 14 22 36 4. Swap rows and columns
10 14 20 22 30 36 5. Result
10 14 20 22 30 36
The logger order and row width are supplied. The construction cannot infer missing labels or repair an incomplete day. Editing this example does not change the workshop tests.
1. Restore Boundaries With reshape
The default reshape order reads the original entries in row order and puts them into the requested row order. It cannot create or discard entries. The product of the new dimensions must match the number of existing entries.
One dimension may be minus one, meaning infer this length from the remaining dimensions and the number of entries. It does not mean a missing observation.
Recover two days from six readings
We know that each day contains three readings, so either give both dimensions or let NumPy infer the day count.
import numpy as np
flat = np.array([10,20,30,14,22,36])
days = flat.reshape(2, 3)
print(days.tolist())
print(flat.reshape(-1, 3).shape)
print(days.ravel().tolist())[[10, 20, 30], [14, 22, 36]]
(2, 3)
[10, 20, 30, 14, 22, 36]ravel returns a flat array in row order. It can return a view or a copy depending on the layout. flatten always copies. Neither operation recovers labels that were never stored.
2. Exchange Axes With Transpose
Regrouping the sequence into three pairs is not the same as following each greenhouse across days. A transpose exchanges the roles of rows and columns while keeping each value attached to its original coordinates.
The T attribute is a convenient transpose for a matrix. On arrays with more axes, name the intended axis order explicitly rather than assuming that reversing all axes is what the task needs.
Compare a reshape with an axis exchange
Both outputs below have three rows and two columns. Inspect their values to see why shape alone cannot establish meaning.
import numpy as np
days = np.array([[10,20,30],[14,22,36]])
print(days.reshape(3, 2).tolist())
print(days.T.tolist())[[10, 20], [30, 14], [22, 36]]
[[10, 14], [20, 22], [30, 36]]Only the transpose places the north greenhouse's two readings together, then the middle's, then the south's. reshape has no knowledge of greenhouse identity.
3. Add Observations or Add an Axis
concatenate extends an existing axis. stack creates a new axis to keep its inputs separate. Suppose we have two daily vectors. Concatenating them makes a longer vector; stacking them makes a table of days.
When joining tables, all dimensions other than the concatenation axis must match. When stacking, the input shapes must match because each becomes a slice along the new axis.
Keep the day boundary when combining reports
We stack two same-length vectors into rows, then append a third row to the resulting table. The third day's extra brackets preserve its row axis.
import numpy as np
monday = np.array([10,20,30])
tuesday = np.array([14,22,36])
print(np.concatenate([monday, tuesday]).shape)
days = np.stack([monday, tuesday], axis=0)
print(days.tolist())
wednesday = np.array([[16,24,38]])
print(np.concatenate([days, wednesday], axis=0).tolist())(6,)
[[10, 20, 30], [14, 22, 36]]
[[10, 20, 30], [14, 22, 36], [16, 24, 38]]The first operation discards the day boundary unless we record it elsewhere. The last operation extends an existing day axis.
4. Keep Features and Batches Distinct
A model often receives a table with observations in rows and features in columns. column_stack turns equally long vectors into feature columns. A batch adds another meaning: a group of observations processed together.
When there are three or more axes, write down what each one means before manipulating the shape. Equal lengths do not make two axes interchangeable.
Build feature columns, then preserve a batch axis
Here each row describes a greenhouse. We keep temperature and humidity in separate columns. expand_dims introduces a new axis of length one; squeeze removes a named axis only if its length is one.
import numpy as np
temperature = np.array([12., 18., 24.])
humidity = np.array([50., 60., 70.])
features = np.column_stack([temperature, humidity])
batch = np.expand_dims(features, axis=0)
print(features.tolist())
print(batch.shape)
print(np.squeeze(batch, axis=0).shape)[[12.0, 50.0], [18.0, 60.0], [24.0, 70.0]]
(1, 3, 2)
(3, 2)The batch shape means one batch, three observations, and two features. Specifying the squeeze axis avoids accidentally removing other meaningful length-one axes.
Check yourself
Questions on Parts 1 to 4
Question 1 of 4
Which operation groups one greenhouse's readings together?
Use this setup. The code is given; its result is for you to work out.
import numpy as np
days = np.array([[10,20,30],[14,22,36]])Try it with Botie
Build with Botie
Write and run Python