Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy "Fortran"-like reshape?

Let's say I have an array X of shape (6, 2) like this:

import numpy as np
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])

I want to reshape it to an array of shape (3, 2, 2), so I did this:

X.reshape(3, 2, 2)

And got:

array([[[ 1,  2],
        [ 3,  4]],

       [[ 5,  6],
        [ 7,  8]],

       [[ 9, 10],
        [11, 12]]])

However, I need my data in a different format. To be precise, I want to end up wth:

array([[[ 1,  2],
        [ 7,  8]],

       [[ 3,  4],
        [ 9,  10]],

       [[ 5, 6],
        [11, 12]]])

Should I be using reshape for this or something else? What's the best way to do this in Numpy?

like image 447
Kosay Jabre Avatar asked Sep 22 '20 19:09

Kosay Jabre


People also ask

How do I reshape an array in NumPy?

Use `.reshape ()` to make a copy with the desired shape. The order keyword gives the index ordering both for fetching the values from a, and then placing the values into the output array. For example, let’s say you have an array: >>> a = np.arange(6).reshape( (3, 2)) >>> a array ( [ [0, 1], [2, 3], [4, 5]]) You can think of reshaping as first ...

How to pass-1 to more than one dimension in NumPy?

Note: We can not pass -1 to more than one dimension. Flattening array means converting a multidimensional array into a 1D array. We can use reshape (-1) to do this. Note: There are a lot of functions for changing the shapes of arrays in numpy flatten, ravel and also for rearranging the elements rot90, flip, fliplr, flipud etc.

How to flatten an array in NumPy?

Flattening array means converting a multidimensional array into a 1D array. We can use reshape (-1) to do this. Note: There are a lot of functions for changing the shapes of arrays in numpy flatten, ravel and also for rearranging the elements rot90, flip, fliplr, flipud etc. These fall under Intermediate to Advanced section of numpy.

Can We reshape an array into a different shape?

Can We Reshape Into any Shape? Yes, as long as the elements required for reshaping are equal in both shapes. We can reshape an 8 elements 1D array into 4 elements in 2 rows 2D array but we cannot reshape it into a 3 elements 3 rows 2D array as that would require 3x3 = 9 elements.


3 Answers

You have to set the order option:

>>> X.reshape(3, 2, 2, order='F')
array([[[ 1,  2],
        [ 7,  8]],

       [[ 3,  4],
        [ 9, 10]],

       [[ 5,  6],
        [11, 12]]])

‘F’ means to read / write the elements using Fortran-like index order, with the first index changing fastest, and the last index changing slowest.

see: https://numpy.org/doc/stable/reference/generated/numpy.reshape.html

like image 144
Philipp Leitl Avatar answered Oct 08 '22 03:10

Philipp Leitl


You need to specify order;

X.reshape(3, 2, 2, order='F')

should work

like image 4
malisit Avatar answered Oct 08 '22 01:10

malisit


A functional equivalent to the order='F' reshape:

In [31]: x.reshape(2,3,2).transpose(1,0,2)
Out[31]: 
array([[[ 1,  2],
        [ 7,  8]],

       [[ 3,  4],
        [ 9, 10]],

       [[ 5,  6],
        [11, 12]]])

In [32]: x.reshape(2,3,2).transpose(1,0,2).strides
Out[32]: (16, 48, 8)

Without the transpose the strides would be (48,16,8).

A thing that's a bit tricky about this layout is that the last dimension remains in 'C' order. It's the just first two dimension that are switched.

The full 'F' layout would be

In [33]: x = np.arange(1,13).reshape(3,2,2,order='F')
In [34]: x
Out[34]: 
array([[[ 1,  7],
        [ 4, 10]],

       [[ 2,  8],
        [ 5, 11]],

       [[ 3,  9],
        [ 6, 12]]])
like image 4
hpaulj Avatar answered Oct 08 '22 01:10

hpaulj