Issue
My input is a list of numbers that are not necessarily sorted but for the example I made a simple one :
my_list = [0, 1, 2, 3, 4]
I want to repeat it n times horizontaly but when i is odd we need to reverse the list :
# [[0, 4, 0, 4, 0, 4],
# [1, 3, 1, 3, 1, 3],
# [2, 2, 2, 2, 2, 2],
# [3, 1, 3, 1, 3, 1],
# [4, 0, 4, 0, 4, 0]]
For that I made the code below but I'm not proud of it.
final = []
for i in range(6):
if i%2 == 0:
final.append(my_list)
else:
final.append(my_list[::-1])
final = list(zip(*final))
I heard that numpy and pandas are more suitable for this kind of operations.
Do you guys have any idea how to do it ? I'm open to any suggestion.
Solution
Using numpy's tile
(or repeat
) and indexing:
my_list = [0, 1, 2, 3, 4]
N = 6
# repeat the array
out = np.tile(np.array(my_list)[:, None], (1, N))
# or
# out = np.repeat(np.array(my_list)[:, None], N, axis=1)
# invert the odd columns
out[:, 1::2] = out[::-1, 1::2]
Or with a small hack that might be faster for large N
, form a pair of columns in the ascending/descending order, then tile
it to the closest upper even value, and slice to remove the last column if even:
N = 6
a = np.array(my_list)
out = np.tile(np.c_[a, a[::-1]], (1, (N+1)//2))[:, :N]
Output:
array([[0, 4, 0, 4, 0, 4],
[1, 3, 1, 3, 1, 3],
[2, 2, 2, 2, 2, 2],
[3, 1, 3, 1, 3, 1],
[4, 0, 4, 0, 4, 0]])
timings
for N = 10_000
:
# first approach
44.9 µs ± 1.14 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
# second approach
24.7 µs ± 1.86 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
# list(zip(*(my_list[::-1] if i%2 else my_list for i in range(N))))
1.33 ms ± 82.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Answered By - mozway
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.