Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does NumPy's transpose() method permute the axes of an array?

In [28]: arr = np.arange(16).reshape((2, 2, 4))  In [29]: arr Out[29]:  array([[[ 0,  1,  2,  3],         [ 4,  5,  6,  7]],         [[ 8,  9, 10, 11],         [12, 13, 14, 15]]])   In [32]: arr.transpose((1, 0, 2)) Out[32]:  array([[[ 0,  1,  2,  3],         [ 8,  9, 10, 11]],         [[ 4,  5,  6,  7],         [12, 13, 14, 15]]]) 

When we pass a tuple of integers to the transpose() function, what happens?

To be specific, this is a 3D array: how does NumPy transform the array when I pass the tuple of axes (1, 0 ,2)? Can you explain which row or column these integers refer to? And what are axis numbers in the context of NumPy?

like image 840
Frank Hu Avatar asked Aug 16 '15 10:08

Frank Hu


People also ask

How does transpose work in NumPy?

This function permutes or reserves the dimension of the given array and returns the modified array. The numpy. transpose() function changes the row elements into column elements and the column elements into row elements. The output of this function is a modified array of the original one.

What does transposing an array do?

The transpose of a matrix is obtained by moving the rows data to the column and columns data to the rows. If we have an array of shape (X, Y) then the transpose of the array will have the shape (Y, X).

What happens when we apply NP transpose () on a one dimensional array?

If we apply T or transpose() to a one-dimensional array, then it returns an array equivalent to the original array.

How do you transpose an array in Python?

Use transpose(a, argsort(axes)) to invert the transposition of tensors when using the axes keyword argument. Transposing a 1-D array returns an unchanged view of the original array.


2 Answers

To transpose an array, NumPy just swaps the shape and stride information for each axis. Here are the strides:

>>> arr.strides (64, 32, 8)  >>> arr.transpose(1, 0, 2).strides (32, 64, 8) 

Notice that the transpose operation swapped the strides for axis 0 and axis 1. The lengths of these axes were also swapped (both lengths are 2 in this example).

No data needs to be copied for this to happen; NumPy can simply change how it looks at the underlying memory to construct the new array.


Visualising strides

The stride value represents the number of bytes that must be travelled in memory in order to reach the next value of an axis of an array.

Now, our 3D array arr looks this (with labelled axes):

enter image description here

This array is stored in a contiguous block of memory; essentially it is one-dimensional. To interpret it as a 3D object, NumPy must jump over a certain constant number of bytes in order to move along one of the three axes:

enter image description here

Since each integer takes up 8 bytes of memory (we're using the int64 dtype), the stride value for each dimension is 8 times the number of values that we need to jump. For instance, to move along axis 1, four values (32 bytes) are jumped, and to move along axis 0, eight values (64 bytes) need to be jumped.

When we write arr.transpose(1, 0, 2) we are swapping axes 0 and 1. The transposed array looks like this:

enter image description here

All that NumPy needs to do is to swap the stride information for axis 0 and axis 1 (axis 2 is unchanged). Now we must jump further to move along axis 1 than axis 0:

enter image description here

This basic concept works for any permutation of an array's axes. The actual code that handles the transpose is written in C and can be found here.

like image 144
Alex Riley Avatar answered Sep 23 '22 01:09

Alex Riley


As explained in the documentation:

By default, reverse the dimensions, otherwise permute the axes according to the values given.

So you can pass an optional parameter axes defining the new order of dimensions.

E.g. transposing the first two dimensions of an RGB VGA pixel array:

 >>> x = np.ones((480, 640, 3))  >>> np.transpose(x, (1, 0, 2)).shape  (640, 480, 3) 
like image 31
Falko Avatar answered Sep 27 '22 01:09

Falko