# NumPy: How to use reshape() and the meaning of -1

Posted: 2019-11-21 / Modified: 2020-09-24 / Tags: Python, NumPy

To convert the shape of a NumPy array `ndarray`, use the `reshape()` method of `ndarray` or the `numpy.reshape()` function.

• How to use `ndarray.reshape()` method
• How to use `numpy.reshape()` function
• Conversion order: `order`
• The meaning of `-1` in `reshape()`
• `reshape()` returns the view

If you want to check the shape or the number of dimensions of `ndarray`, see the following article.

You can use `reshape()` to convert to any shape, but there may be alternatives available for convenience in certain shape conversions.

In addition, in the operation between NumPy arrays (`ndarray`), each `shape` is automatically converted to be the same by broadcasting.

## How to use ndarray.reshape() method

Take the following one-dimensional NumPy array `ndarray` as an example.

``````import numpy as np

a = np.arange(24)

print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

print(a.shape)
# (24,)

print(a.ndim)
# 1
``````

Specify the shape as a list or tuple in the first argument of the `reshape()` method of `numpy.ndarray`.

``````a_4_6 = a.reshape([4, 6])

print(a_4_6)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a_4_6.shape)
# (4, 6)

print(a_4_6.ndim)
# 2
``````
``````a_2_3_4 = a.reshape([2, 3, 4])

print(a_2_3_4)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a_2_3_4.shape)
# (2, 3, 4)

print(a_2_3_4.ndim)
# 3
``````

If the shape does not match the number of elements in the original array, `ValueError` occurs.

``````# a_5_6 = a.reshape([5, 6])
# ValueError: cannot reshape array of size 24 into shape (5,6)
``````

You can specify each dimension value in turn, not a list or tuple.

``````print(a.reshape(4, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape(2, 3, 4))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]
``````

## How to use numpy.reshape() function

In the `numpy.reshape()` function, specify the original `numpy.ndarray` as the first argument and the shape to the second argument as a list or tuple. If the shape does not match the number of elements in the original array, `ValueError` occurs.

``````print(np.reshape(a, [4, 6]))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(np.reshape(a, [2, 3, 4]))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

# print(np.reshape(a, [5, 6]))
# ValueError: cannot reshape array of size 24 into shape (5,6)
``````

The second argument of the `numpy.reshape()` function must be a list or tuple. If you specify the value of each dimension in turn like the `reshape()` method of `numpy.ndarray`, `ValueError` occurs.

``````print(a.reshape(4, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

# print(np.reshape(a, 4, 6))
# ValueError: cannot reshape array of size 24 into shape (4,)
``````

## Conversion order: order

The conversion order can be specified with the argument `order`. `order='C'`(default) means C-like index order, `order='F'` means Fortran-like index order.

The results are different as follows.

``````print(a.reshape([4, 6], order='C'))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape([4, 6], order='F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]

print(a.reshape([2, 3, 4], order='C'))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a.reshape([2, 3, 4], order='F'))
# [[[ 0  6 12 18]
#   [ 2  8 14 20]
#   [ 4 10 16 22]]
#
#  [[ 1  7 13 19]
#   [ 3  9 15 21]
#   [ 5 11 17 23]]]
``````

Same for `numpy.reshape()` function:

``````print(np.reshape(a, [4, 6], order='F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]
``````

The `reshape()` method of `numpy.ndarray` allows you to specify the shape of each dimension in turn as described above, so if you specify the argument `order`, you must use the keyword.

In the `numpy.reshape()` function, the third argument is always `order`, so the keyword can be omitted.

``````# print(a.reshape([4, 6], 'F'))
# TypeError: 'list' object cannot be interpreted as an integer

print(np.reshape(a, [4, 6], 'F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]
``````

## The meaning of -1 in reshape()

You can use `-1` to specify the shape in `reshape()`.

Take the `reshape()` method of `numpy.ndarray` as an example, but the same is true for the `numpy.reshape()` function.

The length of the dimension set to `-1` is automatically determined by inferring from the specified values of other dimensions. This is useful when converting a large array shape.

``````print(a.reshape([4, -1]))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape([2, -1, 4]))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]
``````

You can use `-1` for only one dimension. If used for more than one dimension, `ValueError` occurs.

``````# print(a.reshape([2, -1, -1]))
# ValueError: can only specify one unknown dimension
``````

Also, if there is no value that satisfies the condition, `ValueError` occurs.

``````# print(a.reshape([2, -1, 5]))
# ValueError: cannot reshape array of size 24 into shape (2,newaxis,5)
``````

## reshape() returns the view

Note that both `reshape()` method of `numpy.ndarray` and `numpy.reshape()` function return a view instead of a copy whenever possible. Since it is "as much as possible", a copy may be returned instead of a view depending on the memory layout.

See the following article for views and copies in NumPy.

The following example uses the `reshape()` method of `numpy.ndarray`, but the same applies to `numpy.reshape()` function.

`reshape()` returns a view and shares memory with the original `numpy.ndarray`.

``````a = np.arange(8)
print(a)
# [0 1 2 3 4 5 6 7]

a_2_4 = a.reshape([2, 4])
print(a_2_4)
# [[0 1 2 3]
#  [4 5 6 7]]

print(np.shares_memory(a, a_2_4))
# True
``````

Changing the original object changes the view object returned by `reshape()` as follows:

``````a[0] = 100
print(a)
# [100   1   2   3   4   5   6   7]

print(a_2_4)
# [[100   1   2   3]
#  [  4   5   6   7]]
``````

The same applies to the reverse case. Changing the view object returned by `reshape()` changes the original object.

``````a_2_4[0, 0] = 0
print(a_2_4)
# [[0 1 2 3]
#  [4 5 6 7]]

print(a)
# [0 1 2 3 4 5 6 7]
``````

If you want to get a copy, use the `copy()` method. In this case, changing each object does not affect the other object.

``````a_2_4_copy = a.reshape([2, 4]).copy()
print(a_2_4_copy)
# [[0 1 2 3]
#  [4 5 6 7]]

print(np.shares_memory(a, a_2_4_copy))
# False

a[0] = 100
print(a)
# [100   1   2   3   4   5   6   7]

print(a_2_4_copy)
# [[0 1 2 3]
#  [4 5 6 7]]

a_2_4_copy[0, 0] = 200
print(a_2_4_copy)
# [[200   1   2   3]
#  [  4   5   6   7]]

print(a)
# [100   1   2   3   4   5   6   7]
``````

The following is an example where `reshape()` returns a copy instead of a view:

If the stride in memory is not constant as a result of transforming a step-specified slice, a copy is returned.

``````a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
#  [3 4 5]]

a_step = a[:, ::2]
print(a_step)
# [[0 2]
#  [3 5]]

print(a_step.reshape(-1))
# [0 2 3 5]

print(np.shares_memory(a_step, a_step.reshape(-1)))
# False
``````

For a step-specified slice, if stride is constant, a view is returned.

``````a = np.arange(8).reshape(2, 4)
print(a)
# [[0 1 2 3]
#  [4 5 6 7]]

a_step = a[:, ::2]
print(a_step)
# [[0 2]
#  [4 6]]

print(a_step.reshape(-1))
# [0 2 4 6]

print(np.shares_memory(a_step, a_step.reshape(-1)))
# True
``````