我有一个值数组,t,它总是以递增的顺序排列(但不总是等距排列)。我有另一个值x。我需要在t中找到索引,使t[索引]最接近x。函数必须返回0(x<;t.min())和最大索引(或-1)(x>;t.max())。
我写了两个函数来做这个。第一个,f1,在这个简单的计时测试中要快得多。但我喜欢第二条线只是一条线。此计算将在一个大数组上完成,可能每秒多次。
有谁能想出一些其他的功能,与第一个类似的时间,但与更干净的代码?不如先快一点(速度是最重要的)怎么样?
谢谢!
代码:
import numpy as np
import timeit
t = np.arange(10,100000) # Not always uniform, but in increasing order
x = np.random.uniform(10,100000) # Some value to find within t
def f1(t, x):
ind = np.searchsorted(t, x) # Get index to preserve order
ind = min(len(t)-1, ind) # In case x > max(t)
ind = max(1, ind) # In case x < min(t)
if x < (t[ind-1] + t[ind]) / 2.0: # Closer to the smaller number
ind = ind-1
return ind
def f2(t, x):
return np.abs(t-x).argmin()
print t, '\n', x, '\n'
print f1(t, x), '\n', f2(t, x), '\n'
print t[f1(t, x)], '\n', t[f2(t, x)], '\n'
runs = 1000
time = timeit.Timer('f1(t, x)', 'from __main__ import f1, t, x')
print round(time.timeit(runs), 6)
time = timeit.Timer('f2(t, x)', 'from __main__ import f2, t, x')
print round(time.timeit(runs), 6)
np.searchsorted
是二进制搜索(每次将数组分成两半)。因此,必须以返回最后一个小于x的值而不是返回0的方式实现它。看看这个算法(从here):
刚刚替换了最后一行(was
return -1
)。也改变了论点。由于循环是用Python编写的,因此它可能比第一个循环慢。。。(未设定基准)
这似乎要快得多(对我来说,Python 3.2-win32,numpy 1.6.0):
输出:
使用搜索排序:
编辑:
啊,是的,我知道你在f1就是这么做的。也许下面的f3比f1更容易阅读。
相关问题 更多 >
编程相关推荐