Python 对未知行长的大型文件进行二进制搜索
我正在处理巨大的数据CSV文件。每个文件包含数以百万计的记录,每个记录都有一个键。这些记录按它们的键排序。在搜索特定数据时,我不想浏览整个文件。 我已经看到了这个解决方案: 但它建议您在文件上使用相同长度的行-这在我的案例中不受支持 我曾想过在每行中添加一个填充,然后保持固定的行长,但我想知道是否有更好的方法Python 对未知行长的大型文件进行二进制搜索,python,database,io,binary-search,large-files,Python,Database,Io,Binary Search,Large Files,我正在处理巨大的数据CSV文件。每个文件包含数以百万计的记录,每个记录都有一个键。这些记录按它们的键排序。在搜索特定数据时,我不想浏览整个文件。 我已经看到了这个解决方案: 但它建议您在文件上使用相同长度的行-这在我的案例中不受支持 我曾想过在每行中添加一个填充,然后保持固定的行长,但我想知道是否有更好的方法 我使用的是python,您不必拥有固定宽度的记录,因为您不必进行面向记录的搜索。相反,您可以只执行面向字节的搜索,并确保在执行搜索时重新对齐键。下面是一个(可能有问题)示例,说明如何将链接
我使用的是python,您不必拥有固定宽度的记录,因为您不必进行面向记录的搜索。相反,您可以只执行面向字节的搜索,并确保在执行搜索时重新对齐键。下面是一个(可能有问题)示例,说明如何将链接到的解决方案从面向记录修改为面向字节:
bytes = 24935502 # number of entries
for i, search in enumerate(list): # list contains the list of search keys
left, right = 0, bytes - 1
key = None
while key != search and left <= right:
mid = (left + right) / 2
fin.seek(mid)
# now realign to a record
if mid:
fin.readline()
key, value = map(int, fin.readline().split())
if search > key:
left = mid + 1
else:
right = mid - 1
if key != search:
value = None # for when search key is not found
search.result = value # store the result of the search
bytes=24935502#条目数
对于i,在枚举(列表)中搜索:#列表包含搜索键列表
左,右=0,字节-1
键=无
而钥匙搜索和左键:
左=中+1
其他:
右=中-1
如果是钥匙!=搜索:
值=无#用于未找到搜索键时
search.result=value#存储搜索结果
参考问题的答案是,二进制搜索只适用于固定长度的记录,这是错误的。而且您根本不需要进行搜索,因为您有多个项目要查找。只需一行一行地浏览整个文件,为每一行构建一个包含key:offset
的字典,然后使用每个键对应的偏移量上的os.lseek
跳转到感兴趣的记录
当然,如果您甚至不想读取整个文件一次,那么必须进行二进制搜索。但是,如果建立索引可以在多次查找中摊销,如果您每天只进行一次查找,则可能会保存索引,则无需进行搜索。要解决此问题,您也可以使用二进制搜索,但需要对其进行一点更改:
fp = open('your file')
fp.seek(0, 2)
begin = 0
end = fp.tell()
while (begin < end):
fp.seek((end + begin) / 2, 0)
fp.readline()
line_key = get_key(fp.readline())
if (key == line_key):
pass # find what you want
elif (key > line_key):
begin = fp.tell()
else:
end = fp.tell()
fp=open('您的文件')
fp.seek(0,2)
开始=0
end=fp.tell()
while(开始<结束):
fp.seek((结束+开始)/2,0)
fp.readline()
line\u key=get\u key(fp.readline())
如果(键==行\键):
传球#找到你想要的
elif(键>行\键):
begin=fp.tell()
其他:
end=fp.tell()
也许代码有bug。验证你自己。如果你真的想用最快的方法,请检查性能。@Mat-现在没有选择。我有一个非常有限的最后期限,没有足够的时间从这些数据创建数据库。在字节级别进行二进制搜索,然后在搜索之后找到最近的换行符。sqlite似乎有一个自动csv导入选项。没有人的二进制搜索第一次能正常工作。到现在为止,您可能已经有了一个数据库解决方案并正在运行。你有多少不同的大文件?记录的典型数量是多少?以GB为单位的典型文件大小是多少?键是数字还是字符串?似乎永远找不到第一行。