[英]Python: efficient way to match 2 different length arrays and find index in larger array
我有2个数组: x
和bigx
。 它们的范围相同,但是bigx
还有很多要点。 例如
x = np.linspace(0,10,100)
bigx = np.linspace(0,10,1000)
我想在bigx
找到x
和bigx
匹配2个有效数字的索引。 我需要非常快地执行此操作,因为我需要积分每个步骤的索引。
使用numpy.where
非常慢:
index_bigx = [np.where(np.around(bigx,2) == i) for i in np.around(x,2)]
使用numpy.in1d
快30倍
index_bigx = np.where(np.in1d(np.around(bigx), np.around(x,2) == True)
我还尝试使用zip
和enumerate
因为我知道这应该更快,但返回的是空的:
>>> index_bigx = [i for i,(v,myv) in enumerate(zip(np.around(bigx,2), np.around(x,2))) if myv == v]
>>> print index_bigx
[]
我想我一定在这里弄糊涂了,我想尽可能地优化它。 有什么建议么?
由于bigx
总是均匀分布,因此直接计算索引非常简单:
start = bigx[0]
step = bigx[1] - bigx[0]
indices = ((x - start)/step).round().astype(int)
线性时间,无需搜索。
由于我们将x
映射到bigx
等距的bigx
,因此可以使用np.searchsorted
的合并操作,使用其'left'
选项来模拟索引查找操作。 这是实现-
out = np.searchsorted(np.around(bigx,2), np.around(x,2),side='left')
运行时测试
In [879]: import numpy as np
...:
...: xlen = 10000
...: bigxlen = 70000
...: bigx = 100*np.linspace(0,1,bigxlen)
...: x = bigx[np.random.permutation(bigxlen)[:xlen]]
...:
In [880]: %timeit np.where(np.in1d(np.around(bigx,2), np.around(x,2)))
...: %timeit np.searchsorted(np.around(bigx,2), np.around(x,2),side='left')
...:
100 loops, best of 3: 4.1 ms per loop
1000 loops, best of 3: 1.81 ms per loop
如果只需要元素,这应该起作用:
np.intersect1d(np.around(bigx,2), np.around(x,2))
如果需要索引,请尝试以下操作:
around_x = set(np.around(x,2))
index_bigx = [i for i,b in enumerate(np.around(bigx,2)) if b in around_x]
注意:这些未经测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.