Difficulty: Intermediate
Reshaping arrays is a routine operation in data science and machine learning. The reshape() method returns a new view of the array with a different shape, as long as the total number of elements stays the same. For example, a 1D array of 12 elements can be reshaped into (2, 6), (3, 4), (4, 3), (6, 2), (2, 2, 3), or any other shape whose dimensions multiply to 12. If the total does not match, NumPy raises a ValueError. You can also use -1 as one of the dimensions, and NumPy will infer the correct size automatically: arr.reshape(3, -1) with 12 elements produces shape (3, 4).
The flatten() and ravel() methods both convert a multi-dimensional array into a 1D array, but they differ in a critical way. flatten() always returns a copy of the data, meaning modifications to the flattened array do not affect the original. ravel() returns a view whenever possible, so changes to the raveled array will change the original. In performance-sensitive code, ravel() is preferred because it avoids the memory overhead of copying. If you need to guarantee a copy, use flatten() explicitly.
Broadcasting is NumPy's mechanism for performing operations on arrays with different shapes. When two arrays have different shapes, NumPy tries to make them compatible by virtually expanding the smaller array to match the larger one, without actually copying data. The broadcasting rules are: (1) If the arrays have a different number of dimensions, the shape of the smaller array is padded with ones on the left. (2) Arrays with a size of 1 along a particular dimension are stretched to match the other array's size along that dimension. (3) If sizes disagree along any dimension and neither is 1, broadcasting fails with an error.
A common example of broadcasting is adding a 1D array to each row of a 2D array. If you have a (3, 4) matrix and add a (4,) vector, NumPy broadcasts the vector across all 3 rows. Similarly, to add a column vector, you reshape it to (3, 1) so broadcasting stretches it across all 4 columns. This pattern appears constantly in data normalization, where you subtract the mean and divide by the standard deviation along an axis.
The axis parameter in NumPy functions controls the direction of an operation. For a 2D array with shape (rows, cols), axis=0 means "operate along rows" (resulting in one value per column) and axis=1 means "operate along columns" (resulting in one value per row). A helpful mnemonic: the axis you specify is the axis that gets collapsed. If you have shape (3, 4) and call np.sum(arr, axis=0), axis 0 (the rows) is collapsed, leaving shape (4,). Calling np.sum(arr, axis=1) collapses axis 1 (the columns), leaving shape (3,).
import numpy as np
arr = np.arange(1, 13)
print("Original:", arr)
print("Shape:", arr.shape)
reshaped = arr.reshape(3, 4)
print("Reshaped (3,4):")
print(reshaped)
# Using -1 to infer a dimension
auto = arr.reshape(2, -1)
print("Auto-inferred (2,-1):")
print(auto)
A 12-element 1D array is reshaped into a 3x4 matrix. Using -1 as a dimension lets NumPy compute it automatically: 12 / 2 = 6, so the result is (2, 6).
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("Original:")
print(arr)
flat = arr.flatten()
rav = arr.ravel()
print("Flattened:", flat)
print("Raveled:", rav)
# flatten returns a copy, ravel returns a view
rav[0] = 99
print("After modifying ravel:")
print(arr)
Both flatten and ravel produce 1D arrays. However, ravel returns a view, so modifying rav[0] to 99 also changes the original array. flatten would not have this effect because it returns an independent copy.
import numpy as np
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
row_vector = np.array([10, 20, 30])
result = matrix + row_vector
print("Matrix + row vector:")
print(result)
col_vector = np.array([[100], [200]])
result2 = matrix + col_vector
print("Matrix + col vector:")
print(result2)
The row vector (3,) is broadcast across both rows of the (2,3) matrix, adding 10, 20, 30 to each row. The column vector (2,1) is broadcast across all 3 columns, adding 100 to row 0 and 200 to row 1.
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6]])
print("Array:")
print(arr)
print("Sum all:", np.sum(arr))
print("Sum axis=0 (columns):", np.sum(arr, axis=0))
print("Sum axis=1 (rows):", np.sum(arr, axis=1))
print("Mean axis=0:", np.mean(arr, axis=0))
print("Mean axis=1:", np.mean(arr, axis=1))
axis=0 collapses rows, producing column sums [1+4, 2+5, 3+6] = [5, 7, 9]. axis=1 collapses columns, producing row sums [1+2+3, 4+5+6] = [6, 15]. Without axis, the operation covers all elements.
reshape, flatten, ravel, broadcasting rules, axis parameter