44

Consider an array of the following form (just an example):

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

It's shape is [9,2]. Now I want to transform the array so that each column becomes a shape [3,3], like this:

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

The most obvious (and surely "non-pythonic") solution is to initialise an array of zeroes with the proper dimension and run two for-loops where it will be filled with data. I'm interested in a solution that is language-conform...

3 Answers 3

70
a = np.arange(18).reshape(9,2)
b = a.reshape(3,3,2).swapaxes(0,2)

# a: 
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17]])


# b:
array([[[ 0,  6, 12],
        [ 2,  8, 14],
        [ 4, 10, 16]],

       [[ 1,  7, 13],
        [ 3,  9, 15],
        [ 5, 11, 17]]])
Sign up to request clarification or add additional context in comments.

3 Comments

Note that b now is not contiguous, which means it cannot be reshaped in place: b.reshape(9, 2) returns a copy, not a view of the same data, and b.shape = (9, 2) will raise and error.
Very Very important comment by @Jaime, as the point of Shape is to allow optimistic resizing without a clone. Big deal with massive datasets
Why do you need to swap the axes?
1

numpy has a great tool for this task ("numpy.reshape") link to reshape documentation

a = [[ 0  1]
 [ 2  3]
 [ 4  5]
 [ 6  7]
 [ 8  9]
 [10 11]
 [12 13]
 [14 15]
 [16 17]]

`numpy.reshape(a,(3,3))`

you can also use the "-1" trick

`a = a.reshape(-1,3)`

the "-1" is a wild card that will let the numpy algorithm decide on the number to input when the second dimension is 3

so yes.. this would also work: a = a.reshape(3,-1)

and this: a = a.reshape(-1,2) would do nothing

and this: a = a.reshape(-1,9) would change the shape to (2,9)

Comments

0

There are two possible result rearrangements (following example by @eumiro). Einops package provides a powerful notation to describe such operations non-ambigously

>> a = np.arange(18).reshape(9,2)

# this version corresponds to eumiro's answer
>> einops.rearrange(a, '(x y) z -> z y x', x=3)

array([[[ 0,  6, 12],
        [ 2,  8, 14],
        [ 4, 10, 16]],

       [[ 1,  7, 13],
        [ 3,  9, 15],
        [ 5, 11, 17]]])

# this has the same shape, but order of elements is different (note that each paer was trasnposed)
>> einops.rearrange(a, '(x y) z -> z x y', x=3)

array([[[ 0,  2,  4],
        [ 6,  8, 10],
        [12, 14, 16]],

       [[ 1,  3,  5],
        [ 7,  9, 11],
        [13, 15, 17]]])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.