2

Say I have a 1D numpy array of numbers myArray = ([1, 1, 0, 2, 0, 1, 1, 1, 1, 0, 0 ,1, 2, 1, 1, 1]).

I want to create a 2D numpy array that describe the first (column 1) and last (column 2) indices of any "streak" of consecutive 1's that is longer than 2. So for the example above, the 2D array should look like this:

indicesArray = ([5, 8], [13, 15])

Since there are at least 3 consecutive ones in the 5th, 6th, 7th, 8th places and in the 13th, 14th, 15th places.

Any help would be appreciated.

Zennie
  • 375
  • 1
  • 3
  • 13

1 Answers1

2

Approach #1

Here's one approach inspired by this post -

def start_stop(a, trigger_val, len_thresh=2):
    # "Enclose" mask with sentients to catch shifts later on
    mask = np.r_[False,np.equal(a, trigger_val),False]

    # Get the shifting indices
    idx = np.flatnonzero(mask[1:] != mask[:-1])

    # Get lengths
    lens = idx[1::2] - idx[::2]

    return idx.reshape(-1,2)[lens>len_thresh]-[0,1]

Sample run -

In [47]: myArray
Out[47]: array([1, 1, 0, 2, 0, 1, 1, 1, 1, 0, 0, 1, 2, 1, 1, 1])

In [48]: start_stop(myArray, trigger_val=1, len_thresh=2)
Out[48]: 
array([[ 5,  8],
       [13, 15]])

Approach #2

Another with binary_erosion -

from scipy.ndimage.morphology import binary_erosion

mask = binary_erosion(myArray==1,structure=np.ones((3)))
idx = np.flatnonzero(mask[1:] != mask[:-1])
out = idx.reshape(-1,2)+[0,1]
Divakar
  • 218,885
  • 19
  • 262
  • 358