我正在处理大量数据CSV文件。每个文件包含数百万条记录,每条记录都有一个密钥。记录按其密钥排序。我不想在搜索certian数据时查看整个文件。 我见过这个解决方案:Reading Huge File in Python
但它建议你在文件上使用相同长度的行 - 在我的情况下不支持。
我考虑过为每一行添加一个填充,然后保持一个固定的行长度,但我想知道是否有更好的方法来实现它。
我正在使用python
答案 0 :(得分:7)
您不必拥有固定宽度记录,因为您不必进行面向记录的搜索。相反,您可以只进行面向字节的搜索,并确保在进行搜索时重新对齐键。这是一个(可能是错误的)示例,说明如何修改链接到从面向记录到面向字节的解决方案:
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
答案 1 :(得分:2)
要解决此问题,您还可以使用二进制搜索,但需要更改一下:
以下是示例代码:
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()
也许代码有bug。验证自己。如果你真的想要一个最快的方式,请检查性能。
答案 2 :(得分:1)
关于二进制搜索仅用于固定长度记录的引用问题的答案是错误的。而且您根本不需要进行搜索,因为您有多个要查找的项目。只需一次遍历整个文件一行,为每行构建一个key:offset
字典,然后为每个搜索项跳转到感兴趣的记录,使用os.lseek
对应的偏移量每把钥匙。
当然,如果您不想一次读取整个文件,则必须进行二分查找。但是,如果构建索引可以在多个查找中分摊,如果每天只进行一次查找,可能会保存索引,那么搜索是不必要的。