非单调数组中的有效Numpy搜索

时间:2018-09-28 18:22:42

标签: python numpy

我正在尝试进行类似于searchsorted的操作,但是在数组不是完全单调的情况下。假设我有一个标量c和一维数组x,我想找到所有元素i的索引x[i] < c <= x[i + 1]。重要的是,x并非完全单调。

以下代码有效,但我只想知道这是否是最有效的方法,或者是否有简单的方法:

x = np.array([1,2,3,1,2,3,1,2,3])
c = 2.5
t = c > x[:-1]
u = c <= x[1:]
v = t*u
i = v.nonzero()[0]

或在一行代码中:

i = ( (c > x[:-1]) * (c <= x[1:] ).nonzero()[0]

这是恢复这些索引的最有效方法吗?

另外两个问题。

  1. 是否有一种简单的方法可以将其扩展到c是一维数组,而x是2D数组,其中c具有与“ x中的“行”,我对c的相应“行”中x的每个元素执行此搜索?

  2. 我的最终目标是使用三维案例来做到这一点。也就是说,假设c仍然是具有n元素的一维向量。现在,让x为3D数组,其尺寸为jnk。是否可以对x中的每个“子矩阵”执行上面的#1?基本上,在j次以上执行#1。

例如:

x1 = np.array([1,2,3,1,2,3],[1,2,3,1,2,3],[1,2,3,1,2,3])
x2 = x1 + 1
x = np.array([x1,x2])
c = np.array([1.5,2.5,3.5])

在上面的#1中,当我们比较c和x1时,我们将得到:[[0,4],[1,5],[]]

比较c和x2时,将得到:[[],[0,4],[1,5]]

最后,在#2下,我想得到:

[[[0,4],[1,5],[]],
 [[],[0,4],[1,5]]]

2 个答案:

答案 0 :(得分:3)

我们可以进行一次比较以提供布尔掩码,然后以否定的方式重复使用它来获得另一个比较数组,还可以使用切片-

m = c > x
i = np.flatnonzero( m[:-1] & ~m[1:] )

我们可以通过循环将其扩展为x的{​​{1}}和2D的{​​{1}},并通过循环对其进行最小化计算,方法是预先计算掩码生成以向量化的方式,就像这样-

c

答案 1 :(得分:0)

在这样的任务上,numpy进行了太多的比较。您可以通过Numba赢得5倍的奖励。轻松适应3个维度。

@numba.njit
def ind(x,c):
    res = empty_like(x)
    i=j=0
    while i < x.size-1:
        if x[i]<c and c<=x[i+1]:
            res[j]=i
            j+=1
        i+=1 
    return res[:j]