Reshaping arrays
You can also easily reshape and manipulate arrays in NumPy.
To flatten an array into a 1D array, use .flatten()
.
x = np.array([[0, 1, 2, 3],
[4, 5, 6, 7],
[-6, -5, -4, -3]
])
print(x.flatten())
## [ 0 1 2 3 4 5 6 7 -7 -6 -5 -4]
There is also a similar method called .ravel()
. While .flatten()
returns an array with a copy of the elements, .ravel()
returns an array with a reference to the elements. So modifying an element in an array generated by .ravel()
will also modify the element in the original array. Test this out yourself and compare the difference!
w = np.array([[1, 2, 3], [4, 5, 6]])
v = w.flatten()
v[0] = 10
print(v)
print(w)
v = w.ravel()
v[0] = 10
print(v)
print(w)
To transpose an array, use .transpose()
or .T
print(x.transpose())
## [[ 0 4 -7]
## [ 1 5 -6]
## [ 2 6 -5]
## [ 3 7 -4]]
print(x.T)
## Same as above
To reshape an array to a different shape, use .reshape()
. Obviously, you have to keep the total number of elements the same as in the old array.
print(x)
## [[ 0 1 2 3]
## [ 4 5 6 7]
## [-7 -6 -5 -4]]
print(x.reshape((4,3)))
## [[ 0 1 2]
## [ 3 4 5]
## [ 6 7 -7]
## [-6 -5 -4]]
print(x.reshape((6,2)))
## [[ 0 1]
## [ 2 3]
## [ 4 5]
## [ 6 7]
## [-7 -6]
## [-5 -4]]
print(x.reshape((2,6)))
## [[ 0 1 2 3 4 5]
## [ 6 7 -7 -6 -5 -4]]
# 2D to 3D? No problemo!
print(x.reshape((2,3,2)))
## [[[ 0 1]
## [ 2 3]
## [ 4 5]]
##
## [[ 6 7]
## [-7 -6]
## [-5 -4]]]
# You can use -1 to let NumPy automatically infer the size of the remaining axis
print(x.reshape((2, -1)))
## [[ 0 1 2 3 4 5]
## [ 6 7 -7 -6 -5 -4]]
By default NumPy arrays are reshaped in row-major order, so left-to-right, top-to-bottom for 2D. You can change this to column-major order (like in MATLAB) by assigning a keyword argument order='F'
to .reshape()
(F
stands for Fortran-like order).
print(x)
## [[ 0 1 2 3]
## [ 4 5 6 7]
## [-7 -6 -5 -4]]
print(x.reshape((4,3)))
## [[ 0 1 2]
## [ 3 4 5]
## [ 6 7 -7]
## [-6 -5 -4]]
print(x.reshape((4,3), order='F'))
## [[ 0 5 -5]
## [ 4 -6 3]
## [-7 2 7]
## [ 1 6 -4]]
There is an equivalent method .resize()
, but this modifies the array directly, rather than returning a new array.
print(x)
## [[ 0 1 2 3]
## [ 4 5 6 7]
## [-7 -6 -5 -4]]
x.resize((4,3))
print(x)
## [[ 0 1 2]
## [ 3 4 5]
## [ 6 7 -7]
## [-6 -5 -4]]
Adding a new axis to a NumPy array
You may at some point need to convert 1D arrays to a higher dimensional array.
If you need to add a new axis/dimension to an existing NumPy array, use np.newaxis
.
x = np.array([1, 2, 3, 4, 5, 6])
print(x.shape) ## (6, )
y = x[np.newaxis, :]
print(y.shape) ## (1, 6)
This is useful if you need to convert a NumPy array to a row vector or a column vector.
row_vector = x[np.newaxis, :]
print(row_vector.shape) ## (1, 6)
col_vector = x[:, np.newaxis]
print(col_vector.shape) ## (6, 1)
Alternatively, you can use np.expand_dims()
to achieve the same thing.
row_vector = np.expand_dims(x, axis=0)
print(row_vector.shape) ## (1, 6)
col_vector = np.expand_dims(x, axis=1)
print(col_vector.shape) ## (6, 1)
Removing single-dimensional entries from a NumPy array
Perhaps at some point in your machine learning experiments, you may end up with an array of size (3,1,2)
.
x = np.array([[[1,2]],[[3,4]],[[5,6]]])
print(x)
## [[[1 2]]
## [[3 4]]
## [[5 6]]]
## Note the extra square brackets!
print(x.shape)
## (3, 1, 2)
Depending on what you are doing, the dimension with a single element may not be of use to you. You can convert it to an array of size (3,2)
by .squeeze()
-ing out that singleton dimension.
y = x.squeeze()
print(y)
## [[1 2]
## [3 4]
## [5 6]]
## Compare this to the one above
print(y.shape)
## (3, 2)
.squeeze()
will remove all singleton dimensions. If you only want to remove only a specific dimension, use the optional keyword argument axis
.
x = np.array([[[0], [0], [0]]])
print(x)
## [[[0]
## [0]
## [0]]]
print(x.shape)
## (1, 3, 1)
y = x.squeeze(axis=0)
print(y)
## [[0]
## [0]
## [0]]
print(y.shape)
## (3, 1)
y = x.squeeze(axis=2)
print(y)
## [[0 0 0]]
print(y.shape)
## (1, 3)
Note: Both x.squeeze()
and np.squeeze(x)
can be used. I use x.squeeze()
because I prefer OOP (and it’s shorter!)