Reputation: 2610
I want to assign a value to some segments of an array. I've got indexes of the segments as tuples (start_idx, end_idx). Segments may overlay or be sub-segments of each other.
a = np.zeros(12)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
a[segments] = 1
The results is:
a
>> array([1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0])
How can I mask all segments to get this output:
a
>> array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0])
Upvotes: 4
Views: 219
Reputation: 152677
Just to mention the trivial solution: Use a for
-loop over the segments
and assign to the slices:
import numpy as np
a = np.zeros(12)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
for seg in segments.tolist(): # the "tolist" is just an optimization here, you *could* omit it.
a[seg[0]: seg[1]+1] = 1 # or just "seq[1]" if you want to exclude the end point
print(a)
# array([ 1., 1., 1., 1., 0., 0., 1., 1., 1., 1., 1., 0.])
Upvotes: 1
Reputation: 221584
Here's one vectorized approach with the idea being borrowed from this post
-
def segment_arr(segments, L): # L being length of output array
s = np.zeros(L,dtype=int)
stop = segments[:,1]+1
np.add.at(s,segments[:,0],1)
np.add.at(s,stop[stop<len(s)],-1)
return (s.cumsum()>0).astype(int)
Sample run -
In [298]: segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
In [299]: segment_arr(segments, L=12)
Out[299]: array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0])
Upvotes: 2
Reputation: 214987
One option is to simply loop through the segments, and convert ranges to actual index:
a = np.zeros(10)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
a[[i for s in segments for i in range(*s)]] = 1
a
# array([ 1., 1., 1., 0., 0., 0., 1., 1., 1., 1.])
Upvotes: 1
Reputation: 123
Try this:
a = np.zeros(10)
segments = np.array([(0, 3), (1, 2), (6, 8), (8, 10)])
a[range(3)+range(1,2)+range(6,8)+range(8,10)] = 1
print (a)
Upvotes: 1