这是一种方法-
def start_stop(a, trigger_val): # "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 the start and end indices with slicing along the shifting ones return zip(idx[::2], idx[1::2]-1)
样品运行-
In [216]: mask = [1, 0, 0, 1, 1, 1, 0, 0]In [217]: start_stop(mask, trigger_val=1)Out[217]: [(0, 0), (3, 5)]
用它来获得
0s-
In [218]: start_stop(mask, trigger_val=0)Out[218]: [(1, 2), (6, 7)]
在计时
100000x扩大命令datasize -
In [226]: mask = [1, 0, 0, 1, 1, 1, 0, 0]In [227]: mask = np.repeat(mask,100000)# Original solnIn [230]: %%timeit ...: segments = [] ...: start = 0 ...: for i in range(len(mask) - 1): ...: e1 = mask[i] ...: e2 = mask[i + 1] ...: if e1 == 0 and e2 == 1: ...: start = i + 1 ...: elif e1 == 1 and e2 == 0: ...: segments.append((start, i))1 loop, best of 3: 401 ms per loop# @Yakym Pirozhenko's solnIn [231]: %%timeit ...: slices = np.ma.clump_masked(np.ma.masked_where(mask, mask)) ...: result = [(s.start, s.stop - 1) for s in slices]100 loops, best of 3: 4.8 ms per loopIn [232]: %timeit start_stop(mask, trigger_val=1)1000 loops, best of 3: 1.41 ms per loop



