我正在尝试进行类似于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]
这是恢复这些索引的最有效方法吗?
另外两个问题。
是否有一种简单的方法可以将其扩展到c
是一维数组,而x
是2D数组,其中c
具有与“ x
中的“行”,我对c
的相应“行”中x
的每个元素执行此搜索?
我的最终目标是使用三维案例来做到这一点。也就是说,假设c
仍然是具有n
元素的一维向量。现在,让x
为3D数组,其尺寸为j
乘n
乘k
。是否可以对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]]]
答案 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]