I have a one-dimensional array whose elements are either 1 or 0. Looking at blocks of 8 elements each, I want to reverse the order of elements within a block but leave the order of blocks intact. For instance, let's say we have an array A consisting of two blocks:
A = [0,1,0,0,1,0,1,1,0,1,1,1,0,0,1,0]
After this operation, it needs to be like this:
A = [1,1,0,1,0,0,1,0,0,1,0,0,1,1,1,0]
I have currently this solution:
A.reshape(-1,8)[:,::-1].reshape(-1)
Since I am doing this operation on many and large one dimensional arrays, I want to do it as efficient as possible.
Is there a more efficient solution (like using only one reshape
method)?
I get a minimal speedup by replacing the second reshape with a ravel:
In [1]: A = np.asarray([1,1,0,1,0,0,1,0,0,1,0,0,1,1,1,0])
In [2]: %timeit -r 1000 -n 1000 A.reshape(-1,8)[:,::-1].reshape(-1)
2.12 µs ± 427 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
In [3]: %timeit -r 1000 -n 1000 A.reshape(-1,8)[:,::-1].ravel()
1.47 µs ± 362 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
I also assumed that using flip would further improve the efficiency, but (oddly) this seems to not be true:
In [4]: %timeit -r 1000 -n 1000 np.flip(A.reshape(-1, 8), 1).ravel()
2.39 µs ± 531 ns per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
EDIT:
For large arrays, the efficiency seems to be the other way around:
In [1]: A = np.random.randint(2, size=2**20)
In [2]: %timeit -r 100 -n 100 A.reshape(-1,8)[:,::-1].reshape(-1)
1.01 ms ± 13.4 µs per loop (mean ± std. dev. of 100 runs, 100 loops each)
In [3]: %timeit -r 100 -n 100 A.reshape(-1,8)[:,::-1].ravel()
1.11 ms ± 10.5 µs per loop (mean ± std. dev. of 100 runs, 100 loops each)
In [4]: %timeit -r 100 -n 100 np.flip(A.reshape(-1, 8), 1).ravel()
1.11 ms ± 10.3 µs per loop (mean ± std. dev. of 100 runs, 100 loops each)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With