Find span where condition is True using NumPy Find span where condition is True using NumPy numpy numpy

Find span where condition is True using NumPy


How's one way. First take the boolean array you have:

In [11]: aOut[11]: array([0, 0, 0, 2, 2, 0, 2, 2, 2, 0])In [12]: a1 = a > 1

Shift it one to the left (to get the next state at each index) using roll:

In [13]: a1_rshifted = np.roll(a1, 1)In [14]: starts = a1 & ~a1_rshifted  # it's True but the previous isn'tIn [15]: ends = ~a1 & a1_rshifted

Where this is non-zero is the start of each True batch (or, respectively, end batch):

In [16]: np.nonzero(starts)[0], np.nonzero(ends)[0]Out[16]: (array([3, 6]), array([5, 9]))

And zipping these together:

In [17]: zip(np.nonzero(starts)[0], np.nonzero(ends)[0])Out[17]: [(3, 5), (6, 9)]


If you have access to the scipy library:

You can use scipy.ndimage.measurements.label to identify any regions of non zero value. it returns an array where the value of each element is the id of a span or range in the original array.

You can then use scipy.ndimage.measurements.find_objects to return the slices you would need to extract those ranges. You can access the start / end values directly from those slices.

In your example:

import numpyfrom scipy.ndimage.measurements import label, find_objectsdata = numpy.array([0, 0, 0, 2, 2, 0, 2, 2, 2, 0])labels, number_of_regions = label(data)ranges = find_objects(labels)for identified_range in ranges:    print(identified_range[0].start, identified_range[0].stop)

You should see:

3 56 9

Hope this helps!