0

Suppose, I have a numpy array where:

my_array = np.arange(16).reshape((2, 2, 4))

array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])

And I use the transpose method that accepts a tuple of axis numbers to permute the axes :

np.transpose((1, 0, 2))

array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

How does transpose perform the operation in this case and how does the axes manipulation happen?

meKafka
  • 55
  • 8
  • 2
    When you ask "how", are you asking how the code works under the hood or how to interpret this result, i.e. why is this the result of the operation? – jared Jul 19 '23 at 21:15
  • I am inclined to seek an answer on how to interpret the result? – meKafka Jul 19 '23 at 21:20
  • Is the second result what you're looking for or what you got? Because that is not the actual result of `np.transpose(my_arr, (0,1,2))`. The array would be unchanged from that operation. – jared Jul 19 '23 at 21:29
  • My apologies, I made a blunder. I meant to ask how can I interpret the result of `np.transpose((1, 0, 2))` ? – meKafka Jul 19 '23 at 21:36
  • 1
    P,lay with `np.arange(24).reshape (2,3,4)`.. The change will be more obvious. Under the covers all it does is change `shape` and `strides`. – hpaulj Jul 19 '23 at 21:38
  • 1
    I advise looking at https://stackoverflow.com/questions/53097952/how-to-understand-numpy-strides-for-layman – Learning is a mess Jul 19 '23 at 21:50

1 Answers1

1
In [226]: x=np.arange(16).reshape((2, 2, 4))
In [227]: y=x.transpose(1,0,2)
In [228]: z=x.transpose(0,2,1)
In [229]: x
Out[229]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])
In [230]: y
Out[230]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

The first 2 dimensions have been switched. It's a little hard to visualize since they are the 'plane' and 'row' dimensions. Column, last remains the same.

In [231]: z
Out[231]: 
array([[[ 0,  4],
        [ 1,  5],
        [ 2,  6],
        [ 3,  7]],

       [[ 8, 12],
        [ 9, 13],
        [10, 14],
        [11, 15]]])

Exchanging the last 2 dimensions is easier to visualize. The 2 planes are rotated - rows for columns

In [232]: x.strides
Out[232]: (64, 32, 8)
In [233]: y.strides
Out[233]: (32, 64, 8)
In [235]: z.strides
Out[235]: (64, 8, 32)

for x, strides increase toward the leading dimensions. 8 for the last, columns, one element at a time. 32 is 4*8, the 4 elements per row. and last 2*32 for the planes.

For y, plane and row dimensions have been switched. For z row and column dimensions have been switched.

Now a copy of either y or z restore the strides to the regular C order.

And if the 3 dimension are all different, the transpose is pretty obvious in the shapes:

In [236]: np.arange(24).reshape(2,3,4).shape
Out[236]: (2, 3, 4)
In [237]: np.arange(24).reshape(2,3,4).transpose(1,0,2).shape
Out[237]: (3, 2, 4)
In [238]: np.arange(24).reshape(2,3,4).transpose(2,1,0).shape
Out[238]: (4, 3, 2)
In [239]: np.arange(24).reshape(2,3,4).transpose(0,2,1).shape
Out[239]: (2, 4, 3)
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • The more I dwell into the concept of strides used in numpy, the more I am able to understand it. Thankyou @hpaulj ! – meKafka Jul 20 '23 at 00:23