2010-06-09 63 views
0

有格式在Python中,如何搜索平面文件以获得与特定数值最接近的匹配?

3.343445 1 
3.54564 1 
4.345535 1 
2.453454 1 

的文件数据等高达1000线,我已经数给出如a=2.44443对于给定的文件,我需要找到文件号码的行数这是最贴近给定数字“a”我该如何做到这一点我目前正在通过将整个文件加载到列表中并比较每个元素并找到最接近的一个其他更好的更快方法来做到这一点?

我的代码:我需要RU这对于不同的文件围绕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 
+3

发布您的代码。 – SilentGhost 2010-06-09 17:25:55

回答

8
>>> gen = (float(line.partition(' ')[0]) for line in open(fname)) 
>>> min(enumerate(gen), key=lambda x: abs(x[1] - a)) 
(3, 2.453454) 
+0

肯定比我的代码好,我没有足够的Python思考;-) – 2010-06-09 17:41:37

+0

非常感谢你,这对我有很大的帮助:) – kaushik 2010-06-09 19:35:34

+0

好的代码。 – 2010-06-09 20:41:55

1

检索所有的数字和使用bisect.insort将它们存储在一个排序列表(或随便扔他们以任何顺序和sort自己);然后使用bisect轻松找到下一个较高的和下一个较低的数字,并取两者中较接近的一个。

这种方法(取决于已排序的列表)在算法上比每次需要查找“关闭”数字时迭代整个未排序列表效率高得多。

+0

从这个问题来看,这听起来像是一次性操作,在这种情况下,线性搜索比平均情况下的排序快。 (如果有多个搜索正在进行,那么我当然同意你的意见) – 2010-06-09 17:33:07

+0

实际上,它看起来像OP想要在同一个文件上多次使用不同的数字运行它 - “我需要每次都将这个文件作为不同的文件大约20000次,所以想要一个快速的方法“。 – 2010-06-09 20:31:35

2

如果文件没有排序,否,没有更快的方法。

实际上,让我改述一下:最快的算法是要逐行扫描文件,并将每行上的第一个数字与“目标值”进行比较,并保存差异最小的行号。但从你的描述来看,这听起来像你的实现效率低下。您不需要将整个文件加载到内存中,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的几个不同值,那么对文件进行排序并按照其他答案进行二分查找会变得更快。

0

这里有一个建议。将数据加载到列表中后,按升序对其进行排序。检查列表中最后一项的值,然后如果大于最后一项,则知道它不在列表中。然后开始检查每个值,如果在列表中。停止检查,一旦你的值达到“a”值。然后,您可以将“a”与这两个最后的值进行比较,以查看哪个更接近。

当您最初扫描数据时,请务必将行号存储在您的列表中。这样可以让你在排序后找回它。

0
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 
相关问题