Home > Enterprise >  Create list of zeroes/ones based on whether index is contained in a list of intervals
Create list of zeroes/ones based on whether index is contained in a list of intervals

Time:03-09

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])
  • Related