对大文本数据进行排序

发布于 2024-11-29 13:54:23 字数 109 浏览 0 评论 0原文

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

我已经尝试过蜂巢。我想看看是否可以使用 python 更快地完成此操作。

I have a large file (100 million lines of tab separated values - about 1.5GB in size). What is the fastest known way to sort this based on one of the fields?

I have tried hive. I would like to see if this can be done faster using python.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

东风软 2024-12-06 13:54:23

您是否考虑过使用 *nix sort 程序?从原始角度来看,它可能比大多数 Python 脚本更快。

使用-t $'\t'指定以制表符分隔,-k n指定字段,其中n是字段编号,如果要将结果输出到新文件,请使用 -o outputfile
示例:

sort -t 

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

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

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

Have you considered using the *nix sort program? in raw terms, it'll probably be faster than most Python scripts.

Use -t $'\t' to specify that it's tab-separated, -k n to specify the field, where n is the field number, and -o outputfile if you want to output the result to a new file.
Example:

sort -t 

Will sort input.txt on its 4th field, and output the result to sorted.txt

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

Will sort input.txt on its 4th field, and output the result to sorted.txt

音盲 2024-12-06 13:54:23

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

  1. 创建一个空列表
  2. open文件
  3. 逐行读取它(使用f.readline()),并存储在列表是一个元组,其中包含要排序的值(使用 line.split('\t').strip() 提取)和文件中该行的偏移量(您可以使用该值来排序)。可以通过电话获取f.tell() 在调用 f.readline() 之前)
  4. 关闭 文件
  5. 排序 列表

然后打印排序后的文件,重新打开该文件,对于列表中的每个元素,使用 f.seek(offset) 将文件指针移动到行的开头,f.readline()< /code> 读取该行并打印

优化:您可能希望将行的长度存储在列表中,以便可以在打印阶段使用 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)

you want to build an in-memory index for the file:

  1. create an empty list
  2. open the file
  3. read it line by line (using f.readline(), and store in the list a tuple consisting of the value on which you want to sort (extracted with line.split('\t').strip()) and the offset of the line in the file (which you can get by calling f.tell() before calling f.readline())
  4. close the file
  5. sort the list

Then to print the sorted file, reopen the file and for each element of your list, use f.seek(offset) to move the file pointer to the beginning of the line, f.readline() to read the line and print the line.

Optimization: you may want to store the length of the line in the list, so that you can use f.read(length) in the printing phase.

Sample code (optimized for readability, not speed):

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)
昵称有卵用 2024-12-06 13:54:23

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

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

这可以最大限度地减少文件 I/O 以及在磁盘上移动文件。

Split up into files that can be sorted in memory. Sort each file in memory. Then merge the resulting files.

Merge by reading a portion of each of the files to be merged. The same amount from each file leaving enough space in memory for the merged result. Once merged saving this. Repeating adding blocks of merged data onto the file.

This minimises the file i/o and moving around the file on the disk.

忘年祭陌 2024-12-06 13:54:23

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

I would store the file in a good relational database, index it on the field your are interested in and then read the ordered items.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文