【问题标题】:Find first occurrence of the biggest element smaller than target in array在数组中查找小于目标的最大元素的第一次出现
【发布时间】:2020-04-03 16:46:57
【问题描述】:

我想在小于目标值n 的数组中找到第一次出现的最大元素的索引。我将举一个例子,以使其更清楚。假设我有这个 numpy 数组:

import numpy as np
A = np.array([0.1, 0.2, 0.4, 0.4, 0.7, 0.7, 0.7, 1])

如果我设置目标n = 0.5,那么我想获得两个0.4 之间的最低索引,这两个n 都是数组中的最高元素,小于n。所以,在这种情况下,返回的索引应该是2。如果我设置n = 0.9,那么返回的索引应该是4,这是0.7的最低索引,以此类推……

当然我可以使用for 循环来做到这一点,但我正在寻找一种快速且可读的pythonic 解决方案。到目前为止,我尝试的是基于np.argmin(np.unique(A)<n) -1 的方法,但它们不能按我的意愿工作。例如:

np.argmin(np.unique(A)<0.5) - 1

正确返回2,但是

np.argmin(np.unique(A)<0.9) - 1

返回3,因为它没有计算被np.unique()“压缩”的两次出现的0.4。有人知道如何做到这一点吗?

【问题讨论】:

    标签: python arrays numpy sorting


    【解决方案1】:

    np.nanargmax + np.where 的单线 -

    In [175]: np.nanargmax(np.where(A<n,A,np.nan))
    Out[175]: 2
    

    如果n 为正,则为另一个 -

    In [180]: (A*(A<n)).argmax()
    Out[180]: 2
    

    另一个np.flatnonzero -

    In [114]: idx = np.flatnonzero(A<n)
    
    In [115]: idx[A[idx].argmax()]
    Out[115]: 2
    

    另一个使用更多掩码以提高内存效率 -

    def argmax_lesser_than_thresh(a, n):
        m = A<n
        m2 = m.copy()
        s = np.ones(m.sum(), dtype=bool)
        s[A[m].argmax()] = False
        m2[m] = s
        return (m2!=m).argmax()
    

    正如 cmets 中所讨论的,如果输入数组是一个已排序的数组,我们也可以使用 np.searchsorted,就像这样 -

    (A==A[max(0,np.searchsorted(A,n)-1)]).argmax()
    

    如果nA[0] 相同,则甚至需要额外检查以下内容-

    A[:np.searchsorted(A,n)].argmax()
    

    【讨论】:

    • 这不是为 all 元素计算 A - n
    • @Anteino OP 不想像问题中所述那样循环。我没有循环。并且 argmax 以矢量化方式查找第一个匹配项。因此,它就是这样使用的。
    • 对,那就无视吧;)
    • 哇,谢谢!这里有很多想法:)。实际上,您的第二种方法与我刚刚提出的一种方法非常相似:A[A&lt;n].argmax()。再次感谢所有好的建议!
    • @Tropilio A[A&lt;n].argmax() 如果说 A[0] 是一个很大的数字 (&gt;n) 将不起作用,例如 0.6
    猜你喜欢
    • 2018-05-21
    • 2018-11-14
    • 2011-09-27
    • 1970-01-01
    • 2011-04-17
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    相关资源
    最近更新 更多