0

I'm looking for the royal road to rearrange an array of variable length like

[1, 2, 3, 4, 5, 6]

into something like this:

[1, 3, 5, 2, 4, 6]

The length of the array is always dividable by 3. So I could also have an array like this:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

which should be turned into:

[1, 4, 7, 2, 5, 8, 3, 6, 9]

A real example would look like this:

['X.1', 'X.2', 'Y.1', 'Y.2', 'Z.1', 'Z.2']

which I would like to turn into:

['X.1', 'Y.1', 'Z.1', 'X.2', 'Y.2', 'Z.2']

An array of size 3 or an empty array should remain unmodified.

How would I do that?

Hendrik Wiese
  • 2,010
  • 3
  • 22
  • 49
  • 1
    You've tagged this with `numpy`, but the question is about lists. Do you want a solution in the world of arrays or in the world of pure Python + lists? – Mark Dickinson Oct 01 '15 at 12:48

3 Answers3

3

If a is the name of your NumPy array, you can write:

a.reshape(3, -1).ravel('f')

(This assumes that your array is divisible by 3, as you have stated.)

This method works by first viewing each chunk of len(a) / 3 elements as rows of a 2D array and then unravels that 2D array column-wise.

For example:

>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> a.reshape(3, -1).ravel('f')
array([1, 3, 5, 2, 4, 6])

>>> b = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b.reshape(3, -1).ravel('f')
array([1, 4, 7, 2, 5, 8, 3, 6, 9])
Alex Riley
  • 169,130
  • 45
  • 262
  • 238
2

no numpy solution:

>>> r = range(1,10)
>>> sum([r[i::len(r)/3] for i in range(len(r)/3)],[])
[1, 4, 7, 2, 5, 8, 3, 6, 9]

i used sum for concatenting lists as it is the most self contained and readable example. But as mentioned in the comments, it is certainly not the most efficient one. For efficiency, you can use list (in)comprehension:

>>> r = range(1,10)
>>> [x for y in [r[i::len(r)/3] for i in range(len(r)/3)] for x in y]
[1, 4, 7, 2, 5, 8, 3, 6, 9]

or any of the other methods mentioned here.

Community
  • 1
  • 1
yurib
  • 8,043
  • 3
  • 30
  • 55
0

Using reshape and transpose (or T) will do :

import numpy as np
t = np.arange(1, 10)
t2 = np.reshape(t, [t.shape[0]/3, 3]).T.reshape(len(t))
P. Camilleri
  • 12,664
  • 7
  • 41
  • 76