2010-06-09 68 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 
相關問題