Python for Data course menu
Reshaping and Combining NumPy Arrays
Change the shape of NumPy arrays with reshape, -1, flatten and transpose, add dimensions with newaxis, and combine arrays with concatenate, vstack, hstack and column_stack, plus matrix multiplication with @.
On this page
Data often arrives in one shape and is needed in another: a long list of values that is really a table, two tables that belong side by side, or a column that must become a row. NumPy makes these changes cheap, usually without copying any data.
reshape#
reshape arranges the same elements into a new shape. The total number of elements must not change:
import numpy as np
a = np.arange(12)
print(a)
print(a.reshape(3, 4))
print(a.reshape(2, 6))
print(a.reshape(4, -1)) # -1: "work this dimension out for me"[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]Elements fill the new shape row by row. -1 can be used for one dimension; NumPy computes it from the total (12 ÷ 4 = 3 here).
import numpy as np
try:
np.arange(12).reshape(5, 3)
except ValueError as e:
print("Error:", e)Error: cannot reshape array of size 12 into shape (5,3)Flattening and transposing#
import numpy as np
m = np.array([[1, 2, 3], [4, 5, 6]])
print(m.flatten()) # back to 1D (a copy)
print(m.ravel()) # 1D, a view when possible
print(m.T) # transpose: rows become columns
print(m.shape, m.T.shape)[1 2 3 4 5 6]
[1 2 3 4 5 6]
[[1 4]
[2 5]
[3 6]]
(2, 3) (3, 2)Adding a dimension#
A 1D array of shape (3,) is neither a row nor a column. To make it one explicitly, add a dimension with np.newaxis (or reshape):
import numpy as np
v = np.array([1, 2, 3])
print(v[np.newaxis, :].shape) # a row: (1, 3)
print(v[:, np.newaxis].shape) # a column: (3, 1)
# outer table: every row value plus every column value
print(v[:, np.newaxis] + np.array([10, 20]))(1, 3)
(3, 1)
[[11 21]
[12 22]
[13 23]]This is how you set up broadcasting between two 1D arrays to build a full table.
Combining arrays#
import numpy as np
jan = np.array([[1, 2], [3, 4]])
feb = np.array([[5, 6], [7, 8]])
print(np.concatenate([jan, feb])) # stack rows (axis=0)
print(np.concatenate([jan, feb], axis=1)) # side by side
print(np.vstack([jan, feb]).shape, np.hstack([jan, feb]).shape)
ids = np.array([101, 102, 103])
scores = np.array([88, 92, 79])
print(np.column_stack([ids, scores])) # 1D arrays as columns[[1 2]
[3 4]
[5 6]
[7 8]]
[[1 2 5 6]
[3 4 7 8]]
(4, 2) (2, 4)
[[101 88]
[102 92]
[103 79]]vstack stacks vertically (more rows), hstack horizontally (more columns). The other dimensions must match.
Matrix multiplication#
* multiplies element by element. For matrix multiplication (rows times columns, as in linear algebra and machine learning) use @:
import numpy as np
quantities = np.array([[2, 1, 0], # order 1
[0, 3, 4]]) # order 2
prices = np.array([10, 25, 5]) # price of each item
print(quantities @ prices) # total per order
A = np.array([[1, 2], [3, 4]])
B = np.array([[0, 1], [1, 0]])
print(A @ B)
print(A * B) # element-wise, for comparison[45 95]
[[2 1]
[4 3]]
[[0 2]
[3 0]]For A @ B, the number of columns of A must equal the number of rows of B. You will meet @ again in the Machine Learning course.
Common mistakes#
Practice#
Practice exercise
Hourly visitors for one day are np.arange(24) * 3 (a 1D array of 24 numbers). Reshape it into 4 rows of 6 hours (night, morning, afternoon, evening), print the total visitors for each period, and print the transposed table's shape.
Show hint
reshape(4, 6), then sum(axis=1). The transpose has the dimensions swapped.
Show solution
import numpy as np
visitors = np.arange(24) * 3
day = visitors.reshape(4, 6)
print(day.sum(axis=1))
print(day.T.shape)[ 45 153 261 369]
(6, 4)Key takeaway#
Next, tables with labels: pandas Series.
Finished this lesson?