0

I have a list a and need to convert it to a numpy array b with shape (2, 3, 4) and elements in the following order.

a = [0, 12, 1, 13, 2, 14, 3, 15, 4, 16, 5, 17, 6, 18, 7, 19, 8, 20, 9, 21, 10, 22, 11, 23]

b = 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]]])

I tried a bit and got these two ways:

b = np.rollaxis(np.asarray(a).reshape(3, 4, 2), 2)
b = np.asarray(a).reshape(2,4,3, order="F").swapaxes(1, 2)

Is there any shorter way to do it?

1
  • 3
    You could also stack up a[::2] and a[1::2] and then reshape that. I don’t know if it’ll be much shorter. Ultimately, you’re doing two things: un-interleaving and array, and reshaping an array—and any readable solution is going to involve two steps like your existing ones. Commented Sep 7, 2018 at 20:00

2 Answers 2

5

Using reshape and transpose:

a.reshape(-1, 2).T.reshape(-1, 3, 4)

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]]])

Timings on your sample array:

%timeit np.rollaxis(a.reshape(3, 4, 2), 2)
2.92 µs ± 10.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit a.reshape(2,4,3, order="F").swapaxes(1, 2)
1.1 µs ± 11.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit a.reshape(-1, 2).T.reshape(-1, 3, 4)
1.08 µs ± 7.36 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

I haven't timed this answer on massive arrays because I haven't figured out a way to generalize either of your solutions. One benefit of my solution is that it scales without any altering of the code:

a = np.zeros(48)
a[::2] = np.arange(24)
a[1::2] = np.arange(24, 48) 
a.reshape(-1, 2).T.reshape(-1, 3, 4)

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., 27.],
        [28., 29., 30., 31.],
        [32., 33., 34., 35.]],

       [[36., 37., 38., 39.],
        [40., 41., 42., 43.],
        [44., 45., 46., 47.]]])
Sign up to request clarification or add additional context in comments.

Comments

0

Another way would be:

import numpy as np
np.reshape(sorted(a), (2, 3, 4))

In case you have converted a to an array already, instead do:

np.reshape(np.sort(a), (2, 3, 4))

1 Comment

Inefficient for long arrays.

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.