获取布尔数组中至少n个连续False值的第一个块的索引

00_*_*_00 6 python boolean numpy cumsum

我有一个numpy布尔数组

w=np.array([True,False,True,True,False,False,False])
Run Code Online (Sandbox Code Playgroud)

我想得到第一次有n_at_least假值的索引.比如这里

`n_at_least`=1 -> desired_index=1

`n_at_least`=3 -> desired_index=4
Run Code Online (Sandbox Code Playgroud)

我试过了

np.cumsum(~w)
Run Code Online (Sandbox Code Playgroud)

每次False遇到值时都会增加.但是,当True遇到计数器时,计数器不会再次从0开始,所以我只得到False元素的总数而不是最后连续的计数.

Div*_*kar 6

这是一个矢量化的解决方案,它找到起始、终止索引以及零的长度,最后用于argmax获得满足零计数标准的第一个岛的起始索引是>= n -

def first_occ_index(w, n):
    idx = np.flatnonzero(np.r_[True, w, True])
    lens = np.diff(idx) - 1
    return idx[(lens >= n).argmax()]
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [107]: w
Out[107]: array([ True, False,  True,  True, False, False, False])

In [108]: first_occ_index(w, n=1)
Out[108]: 1

In [109]: first_occ_index(w, n=3)
Out[109]: 4
Run Code Online (Sandbox Code Playgroud)


小智 2

我认为对于这个线性搜索操作,Python 实现是可以的。我的建议是这样的:

def find_block(arr, n_at_least=1):
    current_index = 0
    current_count = 0
    for index, item in enumerate(arr):
         if item:
             current_count = 0
             current_index = index + 1
         else:
             current_count += 1
         if current_count == n_at_least:
             return current_index
    return None # Make sure this is outside for loop
Run Code Online (Sandbox Code Playgroud)

运行该函数会产生以下输出:

>>> import numpy
>>> w = numpy.array([True, False, True, True, False, False, False])
>>> find_block(w, n_at_least=1)
1
>>> find_block(w, n_at_least=3)
4
>>> find_block(w, n_at_least=4)
>>> # None
Run Code Online (Sandbox Code Playgroud)