在Python中,如何在平面文件中搜索最接近某个数值的匹配?

0 投票
5 回答
1236 浏览
提问于 2025-04-15 23:45

我有一个文件,里面的数据格式是这样的:

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

5 个回答

1

首先,获取所有的数字,然后使用bisect.insort这个工具把它们放进一个有序的列表里(或者你也可以随便放,然后自己用sort来排序);接着,利用bisect来轻松找到比目标数字大的下一个数字和比目标数字小的上一个数字,然后选择这两个数字中离目标数字更近的那个。

这种方法(依赖于一个已经排好序的列表)在效率上比每次都遍历整个无序列表来寻找“接近”的数字要高效得多。

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值,那么像其他回答提到的那样先对文件进行排序,然后使用二分查找会更快。

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

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

撰写回答