我有一个numpy
布尔数组
w=np.array([True,False,True,True,False,False,False])
我想获得第一次有n_at_least
个假值的索引。
比如这里
`n_at_least`=1 -> desired_index=1
`n_at_least`=3 -> desired_index=4
我试过了
np.cumsum(~w)
每次遇到False
值时都会增加。
但是,当遇到True
时,计数器不会再次从0开始,所以我只获得False
个元素的总数,而不是最后连续的计数。
答案 0 :(得分:4)
这是一个O(n)numpy解决方案:
yarn add -D coffee-script
答案 1 :(得分:3)
我认为你陷入了只想要使用numpy功能的numpy陷阱。 python有什么问题?此解决方案为O(n)
def f(array, n_at_least):
curr_found_false = 0
curr_index = 0
for index, elem in enumerate(array):
if not elem:
if curr_found_false == 0:
curr_index = index
curr_found_false += 1
if curr_found_false == n_at_least:
return curr_index
else:
curr_found_false = 0
输出
w=np.array([True,False,True,True,False,False,False])
f(w, 1)
# --> 1
f(w, 3)
# --> 4
答案 2 :(得分:3)
这是一个矢量化解决方案,可以找到零的 islands 的开始,停止索引和长度,最后使用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()]
示例运行 -
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
答案 3 :(得分:1)
它应该以这种方式工作:
def n_at_least(n):
for i in range(len(w)):
if not any(w[i:i+n]):
return i
但我不知道是否有更好的方法...
答案 4 :(得分:1)
这是使用带切片的生成器表达式的一种方法:
w = np.array([True,False,True,True,False,False,False])
n = 2
val = False
res = next((i for i, j in enumerate(w[k:k+n] for k in range(len(w)-n+1)) \
if np.all(j==val)), None)
# 4
答案 5 :(得分:1)
我认为对于这种线性搜索操作,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
运行此功能会产生以下输出:
>>> 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