Chapter 11: NumPy Array Reshaping
NumPy Array Reshaping — written exactly like a patient teacher sitting next to you, showing examples, drawing little mental pictures, explaining the rules, warning about common traps, and showing realistic patterns you will actually use in real projects.
Let’s go slowly and thoroughly.
|
0 1 2 3 4 5 6 |
import numpy as np |
1. What does reshaping actually mean?
Reshaping = changing how the data is organized in terms of dimensions, without changing the data itself or the total number of elements.
You are just re-arranging the same numbers into a different grid / cube / structure.
The golden rule you must memorize right now:
The total number of elements must stay exactly the same → product of old shape == product of new shape
Examples:
- 24 elements → can become (4,6), (3,8), (2,3,4), (6,4), (12,2), (24,), etc.
- 24 elements → cannot become (5,5) or (3,7) → ValueError
2. The most important method: .reshape()
|
0 1 2 3 4 5 6 7 8 9 |
a = np.arange(24) print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] print(a.shape) # (24,) |
Now let’s reshape:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 2D matrix – most common case b = a.reshape(4, 6) print(b.shape) # (4, 6) print(b) # [[ 0 1 2 3 4 5] # [ 6 7 8 9 10 11] # [12 13 14 15 16 17] # [18 19 20 21 22 23]] # Different arrangement – same data c = a.reshape(3, 8) print(c) # [[ 0 1 2 3 4 5 6 7] # [ 8 9 10 11 12 13 14 15] # [16 17 18 19 20 21 22 23]] |
Important observation:
NumPy fills the new array row by row (C-order, row-major order) by default.
3. The magic number: -1 (very useful and very common)
You can use -1 in one dimension → NumPy automatically calculates it.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# I know I want 6 columns, don't care about rows d = a.reshape(-1, 6) print(d.shape) # (4, 6) ← same as before # I want 4 rows, don't care about columns e = a.reshape(4, -1) print(e.shape) # (4, 6) # Make it 3D – very common in deep learning f = a.reshape(-1, 3, 4) # -1 → automatically 2 print(f.shape) # (2, 3, 4) |
When students forget -1 and get error:
|
0 1 2 3 4 5 6 7 |
a.reshape(5, 5) # ValueError: cannot reshape array of size 24 into shape (5,5) a.reshape(-1, 5) # works → (4, 5) or (5, ?) depending on numbers |
4. Very common real-world reshaping patterns (you will write these often)
Pattern 1: Flattening images for machine learning
|
0 1 2 3 4 5 6 7 8 9 10 11 |
# 100 RGB images of 28×28 pixels images = np.random.randint(0, 256, (100, 28, 28, 3), dtype=np.uint8) print(images.shape) # (100, 28, 28, 3) flat_images = images.reshape(100, -1) # or images.reshape(100, 28*28*3) print(flat_images.shape) # (100, 2352) |
Pattern 2: Turning flat vectors back into images
|
0 1 2 3 4 5 6 7 8 9 |
# Many ML models return flattened predictions flat = np.random.rand(64, 784) # 64 samples × 784 pixels (28×28) images_reshaped = flat.reshape(64, 28, 28) # or reshape(-1, 28, 28) # or with channels: reshape(-1, 28, 28, 1) for grayscale |
Pattern 3: Preparing time-series / sequence data
|
0 1 2 3 4 5 6 7 8 9 10 |
# 5000 time steps of 16 features ts_data = np.random.randn(5000, 16) # Want windows of 30 timesteps → (samples, timesteps, features) windowed = ts_data.reshape(-1, 30, 16) # assuming divisible |
Pattern 4: Changing channel order (very common in deep learning)
|
0 1 2 3 4 5 6 7 8 9 |
img_batch = np.random.rand(32, 224, 224, 3) # (batch, H, W, C) ← TensorFlow/Keras style img_batch_pytorch = img_batch.transpose(0, 3, 1, 2) # (batch, C, H, W) # or with reshape if you prefer: # img_batch_pytorch = img_batch.reshape(32, 3, 224, 224) |
5. reshape() vs ravel() vs flatten() — important differences
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
arr = np.arange(24).reshape(4, 6) # 1. ravel() → usually returns a **view** (fast, memory efficient) r1 = arr.ravel() r1[0] = 999 print(arr[0,0]) # 999 ← original changed → view! # 2. flatten() → always returns a **copy** (safer when you want independence) f1 = arr.flatten() f1[0] = 777 print(arr[0,0]) # still 999 ← original unchanged # 3. reshape(-1) → same as ravel() in most cases (also usually view) |
Quick rule students should write down:
| Method | Usually returns | Use when… |
|---|---|---|
| .ravel() | View | You want fast flattening and don’t plan to modify |
| .flatten() | Copy | You want a safe, independent 1D copy |
| .reshape(-1) | View (most cases) | You want to flatten or re-arrange safely |
6. Common beginner mistakes with reshaping
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Mistake 1: Wrong number of elements a = np.arange(10) a.reshape(4, 4) # ValueError # Mistake 2: Forgetting tuple a.reshape(3, 4) # correct a.reshape(3 4) # SyntaxError # Mistake 3: Thinking reshape always copies b = a.reshape(2, 5) b[0,0] = 999 print(a) # a also changed! # Mistake 4: Using reshape on non-contiguous array (advanced trap) c = a[::2].reshape(3, -1) # may fail or give unexpected result in some cases |
Summary – Reshaping Cheat Sheet
| What you want to do | Best expression |
|---|---|
| Make 2D matrix with known columns | arr.reshape(-1, num_cols) |
| Make 2D matrix with known rows | arr.reshape(num_rows, -1) |
| Turn image batch into flat vectors | images.reshape(num_images, -1) |
| Turn flat vectors back to images | flat.reshape(-1, height, width, channels) |
| Flatten quickly (don’t care about copy) | arr.ravel() or arr.reshape(-1) |
| Flatten safely (want copy) | arr.flatten() |
| Change order of axes (e.g. HWC → CHW) | transpose() or reshape() with care |
| Check if reshape is possible | arr.size == new_rows * new_cols * … |
Would you like to continue with any of these next?
- Reshape + copy vs view in depth
- Reshaping multi-dimensional arrays (3D, 4D)
- Common reshape patterns in computer vision / NLP
- Debugging “cannot reshape” errors
- Mini-exercise: reshape some image-like data together
Just tell me what you want to focus on now! 😊
