pytutorial/numpy/reshape/README.md
David Rotermund 4fab448f60
Update README.md
Signed-off-by: David Rotermund <54365609+davrot@users.noreply.github.com>
2023-12-14 14:55:37 +01:00

4.2 KiB
Raw Permalink Blame History

Reshape and flatten

{:.no_toc}

* TOC {:toc}

The goal

Sometimes you have to change the shape of a matrix.

Questions to David Rotermund

Reshape

numpy.reshape(a, newshape, order='C')

Gives a new shape to an array without changing its data.

a : array_like Array to be reshaped.

newshape : int or tuple of ints The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length. One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.

order : {C, F, A}, optional Read the elements of a using this index order, and place the elements into the reshaped array using this index order. C means to read / write the elements using C-like index order, with the last axis index changing fastest, back to the first axis index changing slowest. F means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest. Note that the C and F options take no account of the memory layout of the underlying array, and only refer to the order of indexing. A means to read / write the elements in Fortran-like index order if a is Fortran contiguous in memory, C-like order otherwise.

Example:

import numpy as np

a = np.arange(0, 15)

b_2d = np.reshape(a, (5, 3))

print(f"View: {np.may_share_memory(a, b_2d)}") # -> View: True
print(b_2d.shape) # -> (5, 3)
print(b_2d)

Output:

[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]
 [12 13 14]]

image0

Highest dimension is continuously filled first.

import numpy as np

a = np.arange(0, 30)

b_3d = np.reshape(a, (5, 3, 2))

print(f"View: {np.may_share_memory(a, b_3d)}")  # -> View: True
print(b_3d.shape)  # -> (5, 3, 2)
print(b_3d)

Output:

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

 [[ 6  7]
  [ 8  9]
  [10 11]]

 [[12 13]
  [14 15]
  [16 17]]

 [[18 19]
  [20 21]
  [22 23]]

 [[24 25]
  [26 27]
  [28 29]]]

This is how you can expect the data to be reordered (except the view part...)

import numpy as np

a = np.arange(0, 30)

b_3d = np.empty((5, 3, 2))

counter = 0
for idx_0 in range(0, b_3d.shape[0]):
    for idx_1 in range(0, b_3d.shape[1]):
        for idx_2 in range(0, b_3d.shape[2]):
            b_3d[idx_0, idx_1, idx_2] = a[counter]
            counter += 1

print(b_3d)

Output:

[[[ 0.  1.]
  [ 2.  3.]
  [ 4.  5.]]

 [[ 6.  7.]
  [ 8.  9.]
  [10. 11.]]

 [[12. 13.]
  [14. 15.]
  [16. 17.]]

 [[18. 19.]
  [20. 21.]
  [22. 23.]]

 [[24. 25.]
  [26. 27.]
  [28. 29.]]]

.flatten()

.flatten() is the "inverse" operation of reshape

ndarray.flatten(order='C')

Return a copy of the array collapsed into one dimension.

order : {C, F, A, K}, optional C means to flatten in row-major (C-style) order. F means to flatten in column-major (Fortran- style) order. A means to flatten in column-major order if a is Fortran contiguous in memory, row-major order otherwise. K means to flatten a in the order the elements occur in memory. The default is C.

Example:

import numpy as np

a = np.arange(0, 30)
b_3d = np.reshape(a, (5, 3, 2))

c = b_3d.flatten()
print(f"View: {np.may_share_memory(c, b_3d)}")  # -> View: False
print(c.shape)  # -> (30,)
print(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 24 25 26 27 28 29]

Note: This is not a view!

If you want a view, you can use reshape too.

import numpy as np

a = np.arange(0, 30)
b_3d = np.reshape(a, (5, 3, 2))

c = b_3d.reshape((np.prod(b_3d.shape),))
print(f"View: {np.may_share_memory(c, b_3d)}")  # -> View: True
print(c.shape)  # -> (30,)
print(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 24 25 26 27 28 29]