我有一个大文件(1 亿行制表符分隔值 - 大小约为 1.5GB)。根据其中一个字段对其进行排序的最快已知方法是什么?
我试过蜂巢。我想看看这是否可以使用 python 更快地完成。
您是否考虑过使用 *nixsort
程序?用原始术语来说,它可能会比大多数 Python 脚本更快。
用于-t $'\t'
指定它是制表符分隔的,-k n
指定字段,n
字段编号在哪里,以及-o outputfile
是否要将结果输出到新文件。例子:
sort -t $'\t' -k 4 -o sorted.txt input.txt
将对其第 4 个字段进行排序input.txt
,并将结果输出到sorted.txt
你想为文件建立一个内存索引:
open
文件f.readline()
, 并在列表中存储一个元组,该元组包含要排序的值(用 提取line.split('\t').strip()
)和文件中行的偏移量(可以通过在调用f.tell()
之前调用来获得f.readline()
)close
文件sort
名单然后打印排序后的文件,重新打开文件并为列表中的每个元素,使用f.seek(offset)
将文件指针移动到行首,f.readline()
读取行和print
行。
优化:您可能希望将行的长度存储在列表中,以便f.read(length)
在打印阶段使用。
示例代码(针对可读性而非速度进行了优化):
def build_index(filename, sort_col):
index = []
f = open(filename)
while True:
offset = f.tell()
line = f.readline()
if not line:
break
length = len(line)
col = line.split('\t')[sort_col].strip()
index.append((col, offset, length))
f.close()
index.sort()
return index
def print_sorted(filename, col_sort):
index = build_index(filename, col_sort)
f = open(filename)
for col, offset, length in index:
f.seek(offset)
print f.read(length).rstrip('\n')
if __name__ == '__main__':
filename = 'somefile.txt'
sort_col = 2
print_sorted(filename, sort_col)
拆分成可以在内存中排序的文件。对内存中的每个文件进行排序。然后合并生成的文件。
通过读取每个要合并的文件的一部分进行合并。每个文件的数量相同,在内存中为合并结果留出足够的空间。一旦合并保存这个。重复将合并数据块添加到文件中。
这最小化了文件 i/o 并在磁盘上的文件周围移动。
我会将文件存储在一个良好的关系数据库中,在您感兴趣的字段上对其进行索引,然后读取订购的项目。