Home > Back-end >  Figuring out correct numpy transpose for 3*3*3 array
Figuring out correct numpy transpose for 3*3*3 array

Time:02-13

Suppose I have a 3*3*3 array x. I would like to find out an array y, such that such that y[0,1,2] = x[1,2,0], or more generally, y[a,b,c]= x[b,c,a]. I can try numpy.transpose

import numpy as np
x = np.arange(27).reshape((3,3,3))
y = np.transpose(x, [2,0,1])
print(x[0,1,2],x[1,2,0])
print(y[0,1,2])

The output is

5 15
15

The result 15,15 is what I expected (the first 15 is the reference value from x[1,2,0]; the second is from y[0,1,2]) . However, I found the transpose [2,0,1] by drawing in a paper.

B C A
A B C

by inspection, the transpose should be [2,0,1], the last entry in the upper row goes to 1st in the lower row; the middle goes last; the first go middle. Is there any automatic and hopefully efficient way to do it (like any standard function in numpy/sympy)?

Given the input y[a,b,c]= x[b,c,a], output [2,0,1]?

CodePudding user response:

I find easier to explore tranpose with a example with shape like (2,3,4), each axis is different.

But sticking with your (3,3,3)

In [23]: x = np.arange(27).reshape(3,3,3)
In [24]: x
Out[24]: 
array([[[ 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]]])
In [25]: x[0,1,2]
Out[25]: 5

Your sample transpose:

In [26]: y = x.transpose(2,0,1)
In [27]: y
Out[27]: 
array([[[ 0,  3,  6],
        [ 9, 12, 15],
        [18, 21, 24]],

       [[ 1,  4,  7],
        [10, 13, 16],
        [19, 22, 25]],

       [[ 2,  5,  8],
        [11, 14, 17],
        [20, 23, 26]]])

We get the same 5 with

In [28]: y[2,0,1]
Out[28]: 5

We could get that (2,0,1) by applying the same transposing values:

In [31]: idx = np.array((0,1,2))   # use an array for ease of indexing
In [32]: idx[[2,0,1]]
Out[32]: array([2, 0, 1])

The way I think about the trapose (2,0,1), we are moving the last axis, 2, to the front, and preserving the order of the other 2.

With differing dimensions, it's easier to visualize the change:

In [33]: z=np.arange(2*3*4).reshape(2,3,4)
In [34]: z
Out[34]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
In [35]: z.transpose(2,0,1)
Out[35]: 
array([[[ 0,  4,  8],
        [12, 16, 20]],

       [[ 1,  5,  9],
        [13, 17, 21]],

       [[ 2,  6, 10],
        [14, 18, 22]],

       [[ 3,  7, 11],
        [15, 19, 23]]])
In [36]: _.shape
Out[36]: (4, 2, 3)

np.swapaxes is another compiled function for making these changes. np.rollaxis is another, though it's python code that ends up calling transpose.

I haven't tried to follow all of your reasoning, though I think you want a kind reverse of the transpose numbers, one where you specify the result order, and want how to get them.

  • Related