als9xd
als9xd

Reputation: 854

Rotate matrix built from 1d array

Hello I have a sorted list ['a','b','c','d','e','f'] that is currently displayed on the front end as the matrix

['a','c','e'], ['b,'d','f'], When it should be

['a','b','c'], ['d,'e','f'],

Unfortunately I'm not able to modify the front end to display the object horizontally so I would like to be able to rearrange the 1d array into another 1d array with the correct order ['a','d','b','e','c',f'].

I conceptually know how it could be done by converting the 1d array into a 2d array, then rotating the matrix, then converting the 2d array back into a 1d array. However I was wondering if there is a more pythonic way/faster general algorithm for achieving this.

Upvotes: 0

Views: 406

Answers (2)

Luca Cappelletti
Luca Cappelletti

Reputation: 2545

With numpy

I believe the most efficient, considering that you are talking about a GUI and GUI tend to change in size, would be to use numpy to implement your own proposal:

a = np.array(['a','b','c','d','e','f'])
n = len(a)
a.reshape(2, int(n)/2).T.reshape(1,n)

The output is:

array([['a', 'd', 'b', 'e', 'c', 'f']], dtype='<U1')

Speed comparison

Using slicing

Using the solution from the answer of wim:

%timeit [*L[0::3], *L[1::3], *L[2::3]]
>>> 559 ns ± 18 ns per loop

Using Numpy, with conversion to and back

%timeit np.array(L).reshape(2,3).T.reshape(1,6).tolist()
>>> 5.01 µs ± 257 ns per loop

Using Numpy, without conversions

a = np.array(L)
%timeit L.reshape(2,3).T.reshape(1,6)
>>> 1.58 µs ± 84.1 ns per loop

Using slicing with list comprehension

n = int(len(L)/2)
%timeit [j for i in range(n) for j in L[i::n]]
>>> 1.31 µs ± 73.3 ns 

Conclusions

It seems that, for constant sizes, wim answer with slicing is best, followed by slicing with list comprehension when the size is not known beforehand.

Upvotes: 1

wim
wim

Reputation: 362497

Stride it with slices:

>>> L = ['a','b','c','d','e','f']
>>> [*L[0::3], *L[1::3], *L[2::3]]
['a', 'd', 'b', 'e', 'c', 'f']

Consider using numpy if you need to generalise this to arbitrary dimensions:

>>> np.array(L).reshape(2,3).T.ravel().tolist()
['a', 'd', 'b', 'e', 'c', 'f']

Upvotes: 2

Related Questions