spitfiredd
spitfiredd

Reputation: 3135

create non evenly (randomly) spaced arange from a list of index positions?

Suppose I have a array on ones and a list of positions:

arr = np.ones(35)
[3, 5, 8, 12, 14, 17, 19, 25, 27, 33]

At these various points, I want to increase by one so that I have a final array that is something like

array([1,1,1,2,2,3,3,3,4,4,4,4,5,5,6,6,6,7,7,8,8,....])

Upvotes: 1

Views: 145

Answers (4)

GZ0
GZ0

Reputation: 4273

Another solution is to use np.searchsorted:

size = 35
idx = [3, 5, 8, 12, 14, 17, 19, 25, 27, 33]
result = np.searchsorted(idx, np.arange(size), side='right') + 1

Upvotes: 1

hilberts_drinking_problem
hilberts_drinking_problem

Reputation: 11602

You can use repeat with ediff1d.

arr = np.array([3, 5, 8, 12, 14, 17, 19, 25, 27, 33])
res = np.repeat(
    np.arange(1, arr.shape[0] + 1), 
    np.ediff1d(arr, to_begin=arr[0])
)

# array([ 1,  1,  1,  2,  2,  3,  3,  3,  4,  4,  4,  4,  5,  5,  6,  6,  6,
#         7,  7,  8,  8,  8,  8,  8,  8,  9,  9, 10, 10, 10, 10, 10, 10])

This has a flexibility of choosing the first argument to repeat:

In [81]: np.repeat( 
    ...:     [2, 3, 5, 7, 11, 13, 17, 19, 23, 29],  
    ...:     np.ediff1d(arr, to_begin=arr[0]) 
    ...: )                                                               
Out[81]: 
array([ 2,  2,  2,  3,  3,  5,  5,  5,  7,  7,  7,  7, 11, 11, 13, 13, 13,
       17, 17, 19, 19, 19, 19, 19, 19, 23, 23, 29, 29, 29, 29, 29, 29])

Upvotes: 1

sequoia
sequoia

Reputation: 173

You could do something like this:

arr = np.ones(35)
idx = [3, 5, 8, 12, 14, 17, 19, 25, 27, 33]
for val in idx:
    arr[val:] = arr[val:] + 1

(For those unfamilar with Python indexing, the notation [val:] simply indexes from val to the end of the array.)

The output then is:

array([ 1.,  1.,  1.,  2.,  2.,  3.,  3.,  3.,  4.,  4.,  4.,  4.,  5.,
        5.,  6.,  6.,  6.,  7.,  7.,  8.,  8.,  8.,  8.,  8.,  8.,  9.,
        9., 10., 10., 10., 10., 10., 10., 11., 11.])

Upvotes: 2

GZ0
GZ0

Reputation: 4273

arr = np.zeros(35, dtype=int)
idx = [3, 5, 8, 12, 14, 17, 19, 25, 27, 33]
arr[0] = 1
arr[idx] = 1
result = arr.cumsum()

Upvotes: 4

Related Questions