NumPy: Shape Operations

Last updated: 2026-08-26

Shape Operations

1. What You'll Learn



2. A Developer's True Story

(1) The Problem

Bob reshapes 12 data points from 3×4 to 4×3, thinking he's "rearranging memory" — but every reshape was copying data, killing his memory and speed.

(2) The Solution

Alice shows him a Mermaid diagram: "reshape only changes metadata — not a single byte of data moves. That's the secret to NumPy's speed." As long as an operation returns a view, no data is copied.

(3) The Payoff

Once Bob understood "view vs copy," his shape operation code used an order of magnitude less memory and ran several times faster. Only flatten truly copies; everything else — reshape, ravel, transpose, swapaxes — is a view.



3. Shape Operations in Detail

(1) How reshape Works

reshape changes the array's shape but does not copy data. It only modifies the array's metadata (shape and strides); the raw data in memory stays put.

PYTHON
import numpy as np

a = np.arange(12)
b = a.reshape(3, 4)

print(a.shape)   # (12,)
print(b.shape)   # (3, 4)
print(b.base is a)  # True — b is a view of a
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

PYTHON
# reshape does NOT copy data
b[0, 0] = 999
print(a[0])  # 999 — modifying b changes a!
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

reshape Memory Diagram

100%
graph LR
    A["Original Array<br/>shape=(12,)"] -->|"reshape(3,4)"| B["View<br/>shape=(3,4)"]
    A -->|"reshape(4,3)"| C["View<br/>shape=(4,3)"]
    A -->|"reshape(2,6)"| D["View<br/>shape=(2,6)"]

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#9C27B0,color:#fff
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

Key point: A, B, C, and D all share the same memory — they just "interpret" it differently.


(2) -1 Auto-Inference

Use -1 in reshape to let NumPy automatically compute that dimension's size.

PYTHON
a = np.arange(12)

# NumPy infers: 12 / 3 = 4
b = a.reshape(3, -1)     # shape = (3, 4)
c = a.reshape(2, -1)     # shape = (2, 6)
d = a.reshape(-1, 6)     # shape = (2, 6)
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

(3) flatten vs ravel

Method Returns Copies? Memory
ndarray.flatten() 1D array Always copies New memory
ndarray.ravel() 1D array View when possible Usually shared
PYTHON
import numpy as np

a = np.arange(12).reshape(3, 4)

f = a.flatten()  # always a copy
r = a.ravel()    # usually a view

f[0] = 999
print(a[0, 0])   # 0 — f is a copy, a unchanged

r[0] = 999
print(a[0, 0])   # 999 — r is a view, a changed
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

(4) transpose and .T

PYTHON
import numpy as np

a = np.arange(12).reshape(3, 4)
print(a.shape)   # (3, 4)

b = a.T          # transpose — view, no copy
print(b.shape)   # (4, 3)

# For multi-dimensional arrays, transpose accepts an axis order
c = a.transpose(1, 0)
print(c.shape)   # (4, 3)
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

(5) newaxis and squeeze

PYTHON
import numpy as np

a = np.array([1, 2, 3])       # shape (3,)

# newaxis adds a dimension
b = a[np.newaxis, :]           # shape (1, 3)
c = a[:, np.newaxis]           # shape (3, 1)
d = a[np.newaxis, :, np.newaxis]  # shape (1, 3, 1)

# squeeze removes dimensions of size 1
e = np.squeeze(d)              # shape (3,) — back to original
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.


▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: reshape with -1 auto-inference (Difficulty ⭐)

PYTHON
import numpy as np

a = np.arange(24)

# Use -1 for auto-inference
b = a.reshape(2, -1)      # 2 x 12
c = a.reshape(3, -1)      # 3 x 8
d = a.reshape(4, -1)      # 4 x 6
e = a.reshape(6, -1)      # 6 x 4

print(f"a.shape={a.shape}")
print(f"b.shape={b.shape}")  # (2, 12)
print(f"c.shape={c.shape}")  # (3, 8)
print(f"d.shape={d.shape}")  # (4, 6)
print(f"e.shape={e.shape}")  # (6, 4)
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: flatten vs ravel — copy vs view (Difficulty ⭐⭐)

PYTHON
import numpy as np

a = np.arange(12).reshape(3, 4)

# flatten always copies
flat = a.flatten()
flat[0] = 999
print("After flat[0]=999, a[0,0]=", a[0,0])  # 0 (unchanged)

# ravel usually returns a view
rav = a.ravel()
rav[0] = 999
print("After rav[0]=999, a[0,0]=", a[0,0])  # 999 (changed!)
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.

▶ Example

TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.

: transpose and newaxis (Difficulty ⭐⭐)

PYTHON
import numpy as np

a = np.arange(12).reshape(3, 4)

# Transpose
print("Original shape:", a.shape)     # (3, 4)
print("Transposed shape:", a.T.shape)  # (4, 3)

# newaxis: add dimensions
row = np.array([1, 2, 3])
print("row shape:", row.shape)                # (3,)
print("row[np.newaxis,:] shape:", row[np.newaxis, :].shape)  # (1, 3)
print("row[:,np.newaxis] shape:", row[:, np.newaxis].shape)  # (3, 1)
TEXT 📖 Display only
> **Output:** Run NumPy 2.x in your local Python environment to see the ndarray output. The Piston server does not have NumPy pre-installed — install it locally (`pip install numpy`) and compare. Actual values may vary by NumPy version and random seed.
⚠️ Note: The code below needs to run in a local Python environment.



4. Comparison Tables

(1) Shape Operations Summary

Operation Returns Copies Data? Use Case
reshape View No Change shape
flatten Copy Yes Safe 1D conversion
ravel View (usually) Rarely Fast 1D
T / transpose View No Axis reordering
newaxis View No Add dimension
squeeze View No Remove size-1 dims
swapaxes View No Swap two axes

(2) View vs Copy

Feature View Copy
Memory Shared New allocation
Modification Affects original Independent
Speed O(1) O(n)
base attribute Points to original None
When to use Read-only or intentional sharing Safe modification


5. Principle Diagram

100%
graph TB
    A["Original (12,)"] -->|reshape/flatten/ravel| B["New shape"]
    A --> C["data buffer: [0 1 2 ... 11]"]
    B --> C
    B -->|flatten| D["copy of data buffer"]
    B -->|ravel| C
    B -->|transpose| C
    B -->|newaxis| C
    
    style A fill:#4CAF50,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#E91E63,color:#fff


❓ FAQ

Q Does reshape always return a view?
A Almost always — as long as the array is contiguous in memory. If the array is non-contiguous (e.g., after a transpose), reshape may need to copy. Use np.ascontiguousarray() first if needed.
Q What's the difference between .T and .transpose()?
A .T is a shortcut for reversing all axes (equivalent to .transpose() with reversed order). For 2D arrays they're identical. For 3D+, .T reverses all axes, while .transpose(1,0,2) lets you specify the order.
Q When should I use flatten vs ravel?
A If you're going to modify the 1D result and don't want to affect the original, use flatten (safe copy). If you're just reading or you want changes to propagate, use ravel (faster, usually a view).
Q What does -1 mean in reshape?
A It tells NumPy to "figure out this dimension automatically." Only one -1 is allowed. NumPy calculates it as total_size / product_of_other_dims.

📖 Summary



📝 Exercises

  1. Beginner (Difficulty ⭐): Create an array of 20 elements, reshape it to (4,5), (5,4), (2,10), and (10,2) using -1. Verify all shapes are correct.

  2. Intermediate (Difficulty ⭐⭐): Create a 3x4 array, transpose it, then try to reshape the transposed result. Does reshape still avoid copying? Check with .base.

  3. Advanced (Difficulty ⭐⭐⭐): Create a 3D array with shape (2,3,4). Use transpose(2,0,1) to reorder axes. Explain what each dimension represents in the result. Then use swapaxes to achieve the same result.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏