想象一下,我们有一个唯一的整数数组。给定一个整数(N
)的列表,我希望能够尽快得到它的索引(I
)在数组中。搜索字典与搜索排序的numpy结构数组
我的想法是生成一个对象,给定N
返回I
。我虽然使用数据类型为(N,I)
的结构化数组,并按N
排序,或者只是一个带有键N
的字典。
这两种方法的搜索速度似乎都与对象的大小无关,这导致我相信它们受开销控制。但是,我发现搜索字典的速度几乎快于搜索结构化数组的10倍,这让我有点惊讶。所以我的问题是:
- 为什么字典比我的数组实现更快?
- 有没有比这两个更快的替代方法?
MWE:
from __future__ import division
import numpy as np
import timeit
#Time a function
def Timeme(funct,var,NN=10,NNN=10):
for i in xrange(NN):
start =timeit.default_timer()
for t in xrange(NNN):
funct(*var)
end =timeit.default_timer()
print str(i)+': '+str((end - start)/NNN*1000)
#Function to build a dictionary
def mydict(Flist):
Mydict=dict()
for n,i in Flist:
Mydict[n]=i
return Mydict
#Functions to access the data
def myfd(Mydict,vtest):
return Mydict[vtest]
def myfs(Flist,vtest):
n=Flist['N'].searchsorted(vtest)
return Flist['I'][n] #Flist[n]['I'] is slower
#N=100000
N=100
# "Allocate empty structured array"
Flist=np.empty(N,dtype=[('N','i4'),('I','i4')])
# "Fill N with randoms and I with sequence"
Flist['N'] = np.random.randint(N*1000,size=N)
Flist['I'] = np.arange(N)
# "Create test value"
ntest=np.random.randint(N)
vtest=Flist['N'][ntest]
# "Sort array on N"
Flist.sort(order='N')
# "Make dictionary"
Mydict=dict(Flist)
# "Get values"
nrd=myfd(Mydict,vtest)
nrs=myfs(Flist,vtest)
print "Tests OK: " + str(ntest == nrd and ntest == nrs)
print "\nSearch with Dictionary:"
Timeme(myfd,[Mydict,vtest],NN=5,NNN=100)
print "\nSearch directly in Array:"
Timeme(myfs,[Flist,vtest],NN=5,NNN=100)
结果:
Tests OK: True
Search with Dictionary:
0: 0.000404204885682
1: 0.000409016848607
2: 0.000418640774457
3: 0.000404204885682
4: 0.000394580959833
Search directly in Array:
0: 0.00455211692685
1: 0.00465798011119
2: 0.00458580066732
3: 0.00464354422242
4: 0.00476384329554
为什么你使用结构化数组而不仅仅是一个经典的平坦数组? – sascha
当我使用平面阵列进行测试时,它没有改变速度。如果你能想出一种通过使用平面阵列来加速这个过程的方法,请让我知道! – Miguel
@Miguel再次,有*无法*你会比'dict'实现更快的查找。不过,您所做的主要权衡是空间之一。 –