[英]In Python, how do I search a flat file for the closest match to a particular numeric value?
具有格式的文件数据
3.343445 1
3.54564 1
4.345535 1
2.453454 1
等等,直到1000行,我给定了给定文件的数字,例如a=2.44443
,我需要找到文件中最接近给定数字“ a”的数字的行号,我该怎么做目前正在通过将整个文件加载到列表中并比较每个元素并找到最接近的任何其他更快更好的方法来进行操作?
我的代码:我需要在20000次左右每次都针对不同的文件进行处理,因此需要一种快速的方法
p=os.path.join("c:/begpython/wavnk/",str(str(str(save_a[1]).replace('phone','text'))+'.pm'))
x=open(p , 'r')
for i in range(6):
x.readline()
j=0
o=[]
for line in x:
oj=str(str(line).rstrip('\n')).split(' ')
o=o+[oj]
j=j+1
temp=long(1232332)
end_time=save_a[4]
for i in range((j-1)):
diff=float(o[i][0])-float(end_time)
if diff<0:
diff=diff*(-1)
if temp>diff:
temp=diff
pm_row=i
>>> gen = (float(line.partition(' ')[0]) for line in open(fname))
>>> min(enumerate(gen), key=lambda x: abs(x[1] - a))
(3, 2.453454)
如果文件未排序,则不会,没有更快的方法。
实际上,让我改写一下:最快的算法是逐行遍历文件,并将每行的第一个数字与您的“目标值”进行比较,然后将差异最小的行号保存下来。 但是从您的描述看来,您的实现效率很低。 您不需要将整个文件加载到内存中,Python允许您一次遍历整个过程来加载一行。 像这样:
a = 2.44443
min_line = 0
min_diff = Infinity
with open('file.txt', 'r') as f:
for i, line in enumerate(f):
diff = abs(float(line.split()[0]) - a)
if diff < min_diff:
min_line = i
min_diff = diff
编辑 :这假定您将只在文件中搜索a
一个值。 如果你要反复寻找的几个不同的值a
,然后对文件进行排序,并做一个二进制搜索其他答案建议变得更快。
检索所有数字,并使用bisect.insort
将它们存储在排序列表中(或以任何顺序将它们扔给自己sort
); 然后使用bisect
轻松找到下一个较高的数字和下一个较低的数字,并取两者中的较小者。
这种方法(取决于已排序的列表)在算法上比每次需要查找“结束”数字时遍历整个未排序的列表要有效得多。
这是一个建议。 将数据加载到列表中后,按升序对其进行排序。 根据列表中的最后一项检查值,如果大于最后一项,您就知道它不在列表中。 然后开始检查列表中的每个值。 一旦达到高于“ a”值的值,就停止检查。 然后,您可以将“ a”与最后两个值进行比较,以查看哪个更接近。
最初扫描数据时,请确保将行号存储在列表中。 这样可以保留它,以便您在排序后检索它。
a=2.44443
closest = None
f = open('somefile.txt','r')
theLines = f.readlines() #or for really large files theLines = f.xreadlines()
#VALIDATE: I'm asumming at least one file
closest = float(theLines.iter().next().split()[0])
for line in theLines:
b, c = line.split();
b = float(b)
if (abs(a - b) < abs(a - closest)):
closest = b
f.close()
print "The closest is ", b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.