我有兴趣获得满足特定条件的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
?
答案 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