I have a list of lists, each indicating a numeric interval:
intervals = [[1, 4],
[7, 9],
[13, 18]
]
I need to create a list of 20 elements, where each element is 0 if its index is NOT contained in any of the intervals, and 1 otherwise. So, the desired output is:
output = [0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0]
I can think of using something simple, in the lines of:
output = zeros(20)
for index, _ in enumerate(output):
for interval in intervals:
if interval[0] <= index <= interval[1]:
output[index] = 1
but is there a more efficient way?
CodePudding user response:
Essentially the same as @mozway's answer, but without creating an intermediate data structure and arguably more readable:
output = np.zeros(N, dtype=int)
for start, end in intervals:
output[np.arange(start, end 1)] = 1
CodePudding user response:
You could use advanced indexing:
a = np.zeros(20, dtype=int)
idx = np.hstack([np.r_[a:b 1] for a,b in intervals])
# array([ 1, 2, 3, 4, 7, 8, 9, 13, 14, 15, 16, 17, 18])
a[idx] = 1
output:
array([0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0])
CodePudding user response:
There might be a more efficient way to do this, but this might get you started:
intervals = np.array([[1, 4], [7, 9], [13, 18]])
low, high = intervals[:,0], intervals[:,1]
r = np.arange(20)[:,None]
((low <= r) & (high >= r)).any(1).astype(int)
output:
array([0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0])