在numpy中是否有比线性更快的方法来查找布尔条件的端点?

在numpy中是否有比线性更快的方法来查找布尔条件的端点?,numpy,scipy,Numpy,Scipy,有没有人知道一种比线性更快的(常见情况)查找数组布尔属性端点的方法 例如,numpy.nonzero(a)[0][1]是a(维度=0)的最后一个非零元素的索引,类似地,numpy.nonzero(a)[0][0]是第一个非零元素的索引 如果我们知道我们只关心第一个或最后一个元素,我们可以使用更少的内存,并且比上面运行的“非零”运行时具有更好的公共情况运行时。例如,如果我们坚持线性搜索,我们至少可以从适当的一端开始(向后搜索以找到与条件匹配的最后一个值)。或者,我们可以使用二进制搜索(例如,如果中

有没有人知道一种比线性更快的(常见情况)查找数组布尔属性端点的方法

例如,numpy.nonzero(a)[0][1]是a(维度=0)的最后一个非零元素的索引,类似地,numpy.nonzero(a)[0][0]是第一个非零元素的索引

如果我们知道我们只关心第一个或最后一个元素,我们可以使用更少的内存,并且比上面运行的“非零”运行时具有更好的公共情况运行时。例如,如果我们坚持线性搜索,我们至少可以从适当的一端开始(向后搜索以找到与条件匹配的最后一个值)。或者,我们可以使用二进制搜索(例如,如果中间元素与条件匹配,则不需要检查前半部分以查找最后一个元素为真)。
这似乎很常见,可能存在一个现有的实现,但我没有找到类似的实现。

您可以使用
argmax
找到布尔数组的第一个真元素

a = np.array([False, False, True, True, True])
first_True = a.argmax()
last_True = len(a) - 1 - a[::-1].argmax()
您可以使用
argmin
查找假值,这将比使用非零更快,占用的内存更少,但这在
a
的长度上是线性的。如果你想比线性更快,你需要知道
a
是“排序”的,对于一个布尔数组,这意味着你有一个False块,后面跟着all True。在这种情况下,您可以使用搜索排序来查找假与真之间的边界:

first_True = a.searchsorted(True, 'left')

二进制搜索一般不起作用。如果cnetral元素是
True
,我们只需要查看左半部分——这是真的。如果cnetral元素是
False
,这根本不会告诉我们任何事情。很好的解释!(对前面的评论感到抱歉…我在阅读整个答案之前添加了它。)这是一个很好的解决方案,尽管考虑到中没有提到argmax在布尔数组上的特殊行为,这有点不直观。布尔数组没有特殊行为。文件中明确指出,“如果最大值多次出现,则返回与第一次出现对应的索引。”