Skip to main content

Python NumPy: How to Change NumPy Array Dimensions in Python

Reshaping arrays is fundamental for preparing data for machine learning models, matrix operations, and data transformations. NumPy provides several methods to reorganize array dimensions while preserving or modifying the underlying data.

Using reshape() - The Standard Approach

The reshape() method returns a new view of the array with a different shape. The total number of elements must remain constant.

import numpy as np

arr = np.arange(12)
print(f"Original shape: {arr.shape}")

# Reshape to 3 rows, 4 columns
reshaped = arr.reshape(3, 4)
print(f"New shape: {reshaped.shape}")
print(reshaped)

Output:

Original shape: (12,)
New shape: (3, 4)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

The -1 Shortcut for Auto-Calculation

Use -1 to let NumPy calculate one dimension automatically:

import numpy as np

arr = np.arange(12)

# Auto-calculate rows for 4 columns
result = arr.reshape(-1, 4)
print(result.shape) # (3, 4)

# Auto-calculate columns for 3 rows
result = arr.reshape(3, -1)
print(result.shape) # (3, 4)

# Convert to column vector
col_vector = arr.reshape(-1, 1)
print(col_vector.shape) # (12, 1)

Output:

(3, 4)
(3, 4)
(12, 1)
tip

The -1 shortcut is especially useful when you know one dimension but the other depends on your data size-common in ML pipelines.

Shape Must Be Compatible

The total element count must match before and after reshaping:

import numpy as np

arr = np.arange(12) # 12 elements

# ✅ Valid: 3 × 4 = 12
arr.reshape(3, 4)

# ✅ Valid: 2 × 6 = 12
arr.reshape(2, 6)

# ✅ Valid: 2 × 2 × 3 = 12
arr.reshape(2, 2, 3)

# ❌ Invalid: 3 × 5 = 15 ≠ 12
try:
arr.reshape(3, 5)
except ValueError as e:
print(f"Error: {e}")
# Error: cannot reshape array of size 12 into shape (3,5)

Using resize() - Changes Element Count

Unlike reshape(), resize() can change the total number of elements by repeating or truncating data.

np.resize() Function (Repeats Data)

import numpy as np

arr = np.array([1, 2, 3])

# Expand: repeats elements to fill new shape
resized = np.resize(arr, (3, 3))
print(resized)
# [[1 2 3]
# [1 2 3]
# [1 2 3]]

# Expand to different shape
resized = np.resize(arr, (2, 5))
print(resized)
# [[1 2 3 1 2]
# [3 1 2 3 1]]

Output:

[[1 2 3]
[1 2 3]
[1 2 3]]
[[1 2 3 1 2]
[3 1 2 3 1]]

ndarray.resize() Method (Fills with Zeros)

The in-place method pads with zeros instead of repeating:

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6])

# In-place resize (modifies original, pads with zeros)
arr.resize((3, 4))
print(arr)

Output:

[[1 2 3 4]
[5 6 0 0]
[0 0 0 0]]
warning

The in-place resize() method cannot be used if the array is referenced elsewhere. Use np.resize() function for safer operations.

Modifying .shape Directly (In-Place)

Assign a new shape tuple directly to the .shape attribute:

import numpy as np

arr = np.arange(6)
print(f"Before: {arr.shape}")

arr.shape = (2, 3)
print(f"After: {arr.shape}")
print(arr)

Output:

Before: (6,)
After: (2, 3)
[[0 1 2]
[3 4 5]]

This modifies the array in-place and has the same constraints as reshape().

Adding and Removing Dimensions

Adding Dimensions with np.newaxis

import numpy as np

arr = np.array([1, 2, 3])
print(f"Original: {arr.shape}") # (3,)

# Add dimension at the end (column vector)
col = arr[:, np.newaxis]
print(f"Column: {col.shape}") # (3, 1)

# Add dimension at the start (row vector)
row = arr[np.newaxis, :]
print(f"Row: {row.shape}") # (1, 3)

Output:

Original: (3,)
Column: (3, 1)
Row: (1, 3)

Adding Dimensions with expand_dims()

import numpy as np

arr = np.array([1, 2, 3])

# axis=0: add dimension at start
expanded = np.expand_dims(arr, axis=0)
print(expanded.shape) # (1, 3)

# axis=1: add dimension at position 1
expanded = np.expand_dims(arr, axis=1)
print(expanded.shape) # (3, 1)

# axis=-1: add dimension at end
expanded = np.expand_dims(arr, axis=-1)
print(expanded.shape) # (3, 1)

Output:

(1, 3)
(3, 1)
(3, 1)

Removing Dimensions with squeeze()

Remove dimensions of size 1:

import numpy as np

arr = np.array([[[1, 2, 3]]])
print(f"Before: {arr.shape}") # (1, 1, 3)

squeezed = arr.squeeze()
print(f"After: {squeezed.shape}") # (3,)

# Remove specific axis only
arr = np.zeros((1, 3, 1))
print(np.squeeze(arr, axis=0).shape) # (3, 1)
print(np.squeeze(arr, axis=2).shape) # (1, 3)

Output:

Before: (1, 1, 3)
After: (3,)
(3, 1)
(1, 3)

Flattening Arrays

Convert multi-dimensional arrays back to 1D:

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6]])

# flatten() returns a copy
flat = arr.flatten()
print(flat) # [1 2 3 4 5 6]

# ravel() returns a view (more memory efficient)
raveled = arr.ravel()
print(raveled) # [1 2 3 4 5 6]

# reshape(-1) also flattens
flattened = arr.reshape(-1)
print(flattened) # [1 2 3 4 5 6]

Output:

[1 2 3 4 5 6]
[1 2 3 4 5 6]
[1 2 3 4 5 6]
note

Use ravel() for better performance when you don't need a copy. Use flatten() when you need to modify the result without affecting the original.

Transposing Arrays

Swap dimensions using transpose:

import numpy as np

arr = np.arange(6).reshape(2, 3)
print(f"Original shape: {arr.shape}") # (2, 3)
print(arr)
# [[0 1 2]
# [3 4 5]]

# Transpose swaps rows and columns
transposed = arr.T
print(f"Transposed shape: {transposed.shape}") # (3, 2)
print(transposed)
# [[0 3]
# [1 4]
# [2 5]]

# For higher dimensions, specify axis order
arr_3d = np.arange(24).reshape(2, 3, 4)
reordered = arr_3d.transpose(1, 0, 2)
print(reordered.shape) # (3, 2, 4)

Output:

Original shape: (2, 3)
[[0 1 2]
[3 4 5]]
Transposed shape: (3, 2)
[[0 3]
[1 4]
[2 5]]
(3, 2, 4)

Practical ML Examples

Preparing Image Data

import numpy as np

# Single grayscale image (28x28 pixels)
image = np.random.rand(28, 28)

# Add batch and channel dimensions for CNN
# Shape: (batch_size, height, width, channels)
cnn_input = image.reshape(1, 28, 28, 1)
print(f"CNN input shape: {cnn_input.shape}")

Output:

CNN input shape: (1, 28, 28, 1)

Reshaping for sklearn

import numpy as np

# Feature as 1D array
feature = np.array([1.5, 2.3, 3.1, 4.7, 5.2])

# sklearn expects 2D: (n_samples, n_features)
X = feature.reshape(-1, 1)
print(f"sklearn input shape: {X.shape}")

Output:

sklearn input shape: (5, 1)

Batch Processing

import numpy as np

# Flatten batch of images
batch = np.random.rand(32, 28, 28) # 32 images, 28x28 each

# Flatten each image to vector
flattened = batch.reshape(32, -1)
print(f"Flattened batch: {flattened.shape}") # (32, 784)

Output:

Flattened batch: (32, 784)

Method Comparison

MethodChanges Element CountIn-PlaceReturns
reshape()❌ No❌ NoView
np.resize()✅ Yes (repeats)❌ NoCopy
arr.resize()✅ Yes (zeros)✅ YesNone
.shape = ...❌ No✅ YesN/A
squeeze()❌ No❌ NoView
expand_dims()❌ No❌ NoView
flatten()❌ No❌ NoCopy
ravel()❌ No❌ NoView

Summary

  • Use reshape() for standard dimension changes-it's the most common and flexible method.
  • Use -1 to auto-calculate one dimension.
  • For adding single dimensions, np.newaxis or expand_dims() provide clear intent.
  • Use np.resize() only when you need to change the total element count by repeating data.