numpy.argmin表示元素大于阈值

时间:2016-06-22 16:02:32

标签: python arrays performance numpy

我有兴趣获得满足特定条件的1-d NumPy数组中最小值的位置(在我的情况下,中等阈值)。例如:

import numpy as np

limit = 3
a = np.array([1, 2, 4, 5, 2, 5, 3, 6, 7, 9, 10])

我希望有效地屏蔽a中限制范围内的所有数字,以便np.argmin的结果为6.是否有一种计算上廉价的方法来屏蔽值不符合条件,然后申请np.argmin

2 个答案:

答案 0 :(得分:5)

您可以存储有效索引并使用它们来选择a中的有效元素,并使用所选元素中的argmin()索引以获得最终索引输出。因此,实现看起来像这样 -

valid_idx = np.where(a >= limit)[0]
out = valid_idx[a[valid_idx].argmin()]

示例运行 -

In [32]: limit = 3
    ...: a = np.array([1, 2, 4, 5, 2, 5, 3, 6, 7, 9, 10])
    ...: 

In [33]: valid_idx = np.where(a >= limit)[0]

In [34]: valid_idx[a[valid_idx].argmin()]
Out[34]: 6

运行时测试 -

对于性能基准测试,在本节中,我将other solution based on masked array与基于常规数组的解决方案进行比较,如本文前面针对各种数据化所提出的那样。

def masked_argmin(a,limit): # Defining func for regular array based soln
    valid_idx = np.where(a >= limit)[0]
    return valid_idx[a[valid_idx].argmin()]

In [52]: # Inputs
    ...: a = np.random.randint(0,1000,(10000))
    ...: limit = 500
    ...: 

In [53]: %timeit np.argmin(np.ma.MaskedArray(a, a<limit))
1000 loops, best of 3: 233 µs per loop

In [54]: %timeit masked_argmin(a,limit)
10000 loops, best of 3: 101 µs per loop

In [55]: # Inputs
    ...: a = np.random.randint(0,1000,(100000))
    ...: limit = 500
    ...: 

In [56]: %timeit np.argmin(np.ma.MaskedArray(a, a<limit))
1000 loops, best of 3: 1.73 ms per loop

In [57]: %timeit masked_argmin(a,limit)
1000 loops, best of 3: 1.03 ms per loop

答案 1 :(得分:2)

这可以简单地使用numpy的MaskedArray

来完成
import numpy as np

limit = 3
a = np.array([1, 2, 4, 5, 2, 5, 3, 6, 7, 9, 10])
b = np.ma.MaskedArray(a, a<3)
np.ma.argmin(b)    # == 6