Search code examples
pythonnumpyoptimization

How to get as fast as possible a specific sequence of numbers (all numbers twice, except for the first and last) with numpy?


Knowing a final number (for example 5), I would like to create an array containing the following sequence:

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

Meaning that the list should contain all numbers repeated twice, except for the first and last.

Here is the code I use to achieve this :


import numpy as np

# final number
last = 35
# first sequence
sa = np.arange(0,last,1)
# second sequence (shifted by 1 unit)
sb = np.arange (1,last+1,1) 
# concatenation and flattening
sequence = np.stack((sa, sb), axis=1).ravel()
# view the result
print(sequence)

Do you think there would be a more direct and/or effective way to achieve the same result?


Solution

  • What about using arange on 2*N, add 1 and take the floor division by 2?

    N = 5
    
    out = (np.arange(2*N)+1)//2
    
    # or variant suggested by @TlsChris
    # out = (np.arange(2*N)+1)>>1
    

    Alternatively, with repeat and excluding the first/last:

    out = np.repeat(np.arange(N+1), 2)[1:-1]
    

    Or with broadcasting:

    out = (np.arange(N)[:, None]+[0, 1]).ravel()
    

    Output: array([0, 1, 1, 2, 2, 3, 3, 4, 4, 5])

    timings

    Comparison of the different answers

    enter image description here

    Relative timings, around 10,000 items, the original answer seems to be the most efficient, otherwise np.repeat(np.arange(N+1), 2)[1:-1] is the fastest:

    enter image description here