11

我有一个大文件(1 亿行制表符分隔值 - 大小约为 1.5GB)。根据其中一个字段对其进行排序的最快已知方法是什么?

我试过蜂巢。我想看看这是否可以使用 python 更快地完成。

4

4 回答 4

18

您是否考虑过使用 *nixsort程序?用原始术语来说,它可能会比大多数 Python 脚本更快。

用于-t $'\t'指定它是制表符分隔的,-k n指定字段,n字段编号在哪里,以及-o outputfile是否要将结果输出到新文件。例子:

sort -t $'\t' -k 4 -o sorted.txt input.txt

将对其第 4 个字段进行排序input.txt,并将结果输出到sorted.txt

于 2011-08-16T14:20:57.923 回答
5

你想为文件建立一个内存索引:

  1. 创建一个空列表
  2. open文件
  3. 逐行读取(使用f.readline(), 并在列表中存储一个元组,该元组包含要排序的值(用 提取line.split('\t').strip())和文件中行的偏移量(可以通过在调用f.tell()之前调用来获得f.readline()
  4. close文件
  5. 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)
于 2011-08-16T14:23:44.557 回答
4

拆分成可以在内存中排序的文件。对内存中的每个文件进行排序。然后合并生成的文件。

通过读取每个要合并的文件的一部分进行合并。每个文件的数量相同,在内存中为合并结果留出足够的空间。一旦合并保存这个。重复将合并数据块添加到文件中。

这最小化了文件 i/o 并在磁盘上的文件周围移动。

于 2011-08-16T14:34:07.207 回答
2

我会将文件存储在一个良好的关系数据库中,在您感兴趣的字段上对其进行索引,然后读取订购的项目。

于 2011-08-16T14:21:04.790 回答