How to generate a cyclic sequence of numbers without using a loop?

I want to create a cyclic sequence of numbers like: [A B C A B C]with an arbitrary length NI tried:

import numpy as np
def cyclic(N):
    x = np.array([1.0,2.0,3.0]) # The main sequence
    y = np.tile(x,N//3) # Repeats the sequence N//3 times 
    return y

but the problem with my code is that if I enter any integer that is not divisible by three, then the results will have a shorter length ( N) than I tried. I know this is a very newbie, but I'm really stuck.

+4
source share
5 answers

You can just use numpy.resize

x = np.array([1.0, 2.0, 3.0])

y = np.resize(x, 13)

y
Out[332]: array([ 1.,  2.,  3.,  1.,  2.,  3.,  1.,  2.,  3.,  1.,  2.,  3.,  1.])

WARNING. This answer does not apply to 2D, as it resizealigns the array before repeating.

+5
source

№1:. modulus -

def cyclic_seq(x, N):
    return np.take(x, np.mod(np.arange(N),len(x)))

№ 2: , slicing, N -

def cyclic_seq_v2(x, N):   
    return np.tile(x,(N+N-1)//len(x))[:N]

-

In [81]: cyclic_seq([6,9,2,1,7],14)
Out[81]: array([6, 9, 2, 1, 7, 6, 9, 2, 1, 7, 6, 9, 2, 1])

In [82]: cyclic_seq_v2([6,9,2,1,7],14)
Out[82]: array([6, 9, 2, 1, 7, 6, 9, 2, 1, 7, 6, 9, 2, 1])

In [327]: x = np.random.randint(0,9,(3))

In [328]: %timeit np.resize(x, 10000) # @Daniel Forsman solution
     ...: %timeit list(itertools.islice(itertools.cycle(x),10000)) # @Chris soln
     ...: %timeit cyclic_seq(x,10000) # Approach #1 from this post
     ...: %timeit cyclic_seq_v2(x,10000) # Approach #2 from this post
     ...: 
1000 loops, best of 3: 296 µs per loop
10000 loops, best of 3: 185 µs per loop
10000 loops, best of 3: 120 µs per loop
10000 loops, best of 3: 28.7 µs per loop

In [329]: x = np.random.randint(0,9,(30))

In [330]: %timeit np.resize(x, 10000) # @Daniel Forsman solution
     ...: %timeit list(itertools.islice(itertools.cycle(x),10000)) # @Chris soln
     ...: %timeit cyclic_seq(x,10000) # Approach #1 from this post
     ...: %timeit cyclic_seq_v2(x,10000) # Approach #2 from this post
     ...: 
10000 loops, best of 3: 38.8 µs per loop
10000 loops, best of 3: 101 µs per loop
10000 loops, best of 3: 115 µs per loop
100000 loops, best of 3: 13.2 µs per loop

In [331]: %timeit np.resize(x, 100000) # @Daniel Forsman solution
     ...: %timeit list(itertools.islice(itertools.cycle(x),100000)) # @Chris soln
     ...: %timeit cyclic_seq(x,100000) # Approach #1 from this post
     ...: %timeit cyclic_seq_v2(x,100000) # Approach #2 from this post
     ...: 
1000 loops, best of 3: 297 µs per loop
1000 loops, best of 3: 942 µs per loop
1000 loops, best of 3: 1.13 ms per loop
10000 loops, best of 3: 88.3 µs per loop

, approach #2, , .

+2

itertools.cycle, , :

>>> import itertools
>>> it = itertools.cycle([1,2,3])
>>> next(it)
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
1

(N), itertools.islice:

>>> list(itertools.islice(itertools.cycle([1,2,3]),11))
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2]

EDIT: Divakar, . , , return ed, list numpy.

+1

( math.ceil), resize tile

import numpy as np
import math
def cyclic(N):
    x = np.array([1.0,2.0,3.0]) # The main sequence
    y = np.tile(x, math.ceil(N / 3.0))
    y = np.resize(y, N)
    return y

Daniel Forsman

import numpy as np
def cyclic(N):
    x = np.array([1.0,2.0,3.0]) # The main sequence
    y = np.resize(x, N)
    return y

np.resize 1D

+1

itertools .

In [3]: from itertools import cycle
In [4]: for x in cycle(['A','B','C']):
...:     print(x)
...:
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
A
B

Edit: If you want to implement it using loops, you will need recursive functions. Decisions based on the itertools loop, etc., simply hide the loops behind the imported function.

In [5]: def repeater(arr, n):
   ...:     yield arr[0]
   ...:     yield arr[1]
   ...:     yield arr[2]
   ...:     if n == 0:
   ...:         yield StopIteration
   ...:     else:
   ...:          yield from repeater(arr, n-1)
   ...:  
0
source

Source: https://habr.com/ru/post/1674447/


All Articles