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.
12 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.
The logger entries are illustrative and arrive in complete-day order.
Step 1 of 3
Read the logger's order
The first three values belong to Monday and the next three to Tuesday.
Sequence
- Logger position 110
- Logger position 220
- Logger position 330
- Logger position 414
- Logger position 522
- Logger position 636
Step 2 of 3
Restore the day boundary
Group consecutive triples into day rows.
| Day | North | Middle | South |
|---|---|---|---|
| Monday | 10 | 20 | 30 |
| Tuesday | 14 | 22 | 36 |
Monday
- North
- 10
- Middle
- 20
- South
- 30
Tuesday
- North
- 14
- Middle
- 22
- South
- 36
Step 3 of 3
Then follow a greenhouse instead
Swapping axes puts each greenhouse's two readings together.
| Greenhouse | Monday | Tuesday |
|---|---|---|
| North | 10 | 14 |
| Middle | 20 | 22 |
| South | 30 | 36 |
North
- Monday
- 10
- Tuesday
- 14
Middle
- Monday
- 20
- Tuesday
- 22
South
- Monday
- 30
- Tuesday
- 36
Reshaping groups entries; transposing changes the axes
Grouping restores the day boundaries. Transpose then follows greenhouse identity across those days.
Recover the days hidden in the logger's flat list
The logger writes one complete day before starting another. Try a small list whose values you can recognise, then follow one greenhouse through the restored rows and columns.
BOTIE
Recovered greenhouse histories
| 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.
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.
5. A Valid Shape Can Still Mix Up Our Records
Botie's logger sent two days of readings from three greenhouses. We can reshape those six numbers into several valid tables. But reshape only follows the sequence of entries and gives it new boundaries. It has no way to know which readings belong to Monday.
Transpose does a different job: it exchanges the existing axes, so the relationships between days and greenhouses remain attached to their positions. This becomes important when we flatten an image or a batch for a model. We need to remember the original axis order to reconstruct it; getting the dimensions right alone does not put every value back where it belongs.
Two different three-by-two tables
Use visibly different daily values so we can follow their positions.
import numpy as np
a = np.array([[10, 11, 12], [20, 21, 22]])
print(a.reshape(3, 2).tolist())
print(a.T.tolist())[[10, 11], [12, 20], [21, 22]]
[[10, 20], [11, 21], [12, 22]]Only the transposed table puts one greenhouse in each row with its two days beside each other.
6. Add a Batch Without Erasing Its Boundary
concatenate joins along an existing axis. If its inputs are daily tables, joining along axis zero makes a longer table of days. stack creates a new axis, so equal-shaped weekly tables can remain separate weeks.
The choice affects later reductions. A mean over the new week axis compares corresponding positions between weeks; a mean over concatenated days treats all days as one collection. Neither is automatically correct. Use the structure required by the question, and keep calendar labels when a position alone does not identify the observation.
Check yourself
Questions on Parts 1 to 6
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