【问题标题】:Efficient way to read/write/parse large text files (python)读取/写入/解析大型文本文件的有效方法(python)
【发布时间】:2011-12-20 23:05:16
【问题描述】:

假设我有一个大得离谱的文本文件。我认为我的文件不会超过 ~500mb,但为了可扩展性和我自己的好奇心,假设它大约是几个 gig。

我的最终目标是将其映射到一组句子(由“?”、“!”、“。”分隔,并且出于所有意图和目的,使用“;”)并将每个句子映射到一组单词。然后我打算使用 numpy 进行一些统计分析。

最可扩展的方式是什么?

PS:我曾想过将文件重写为每行一个句子,但在尝试将文件加载到内存时遇到了问题。我知道一种解决方案,您可以读取一个文件中的数据块,操作它们,然后将它们写入另一个文件,但这对于磁盘内存来说似乎效率低下。我知道,现在大多数人不会担心使用 10gig 的暂存空间,但似乎应该有一种直接编辑文件的方法。

【问题讨论】:

  • 出于所有密集目的出于所有意图和目的
  • 为什么不使用数据库,比如 sqllite?
  • 您为什么不直接将文件扫描为流并保持计数呢?解析不会很复杂吧?
  • 说实话,我不知道如何使用sqllite。然而,我对 python 很满意。
  • 你真的需要分句,还是只分词?

标签: python regex parsing


【解决方案1】:

我的第一个想法是使用流解析器:基本上,您一次读取一个文件,然后进行统计分析。这通常是使用 HTML 和 XML 等标记语言完成的,因此您会发现很多针对这些语言的解析器,包括 Python 标准库。不过,您可以自己编写一个简单的句子解析器;例如:

import re, collections
sentence_terminator = re.compile(r'(?<=[.!?;])\s*')
class SentenceParser(object):
    def __init__(self, filelike):
        self.f = filelike
        self.buffer = collections.deque([''])
    def next(self):
        while len(self.buffer) < 2:
            data = self.f.read(512)
            if not data:
                raise StopIteration()
            self.buffer += sentence_terminator.split(self.buffer.pop() + data)
        return self.buffer.popleft()
    def __iter__(self):
        return self

这只会根据需要从文件中读取数据以完成一个句子。它读取 512 字节的块,因此无论实际文件有多大,您在任何时候都将在内存中保存不到一千字节的文件内容。

在流解析器之后,我的第二个想法是memory map 文件。这样你就可以遍历并用换行符替换(大概)每个句子终止符后面的空格;之后,每个句子都会从新行开始,您可以打开文件并使用readline()for 循环逐行遍历它。但是您仍然需要担心多行句子;另外,如果任何句子终止符 not 后跟一个空白字符,则您必须插入一个换行符(而不是用它替换其他内容),这对于大文件来说效率可能非常低。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 2016-06-28
    相关资源
    最近更新 更多