说我有一个荒谬的大文本文件。我不认为我的文件会比@ 500mb大,但为了扩展性和我自己的好奇心,让我们说这是几个演出的顺序。
我的最终目标是将其映射到一个句子数组(由'?''!''。'和所有意图和目的';'分隔),每个句子都是一个单词数组。然后,我将使用numpy进行一些统计分析。
最具可扩展性的方法是什么?
PS:我想重写文件每行有一个句子,但是在尝试将文件加载到内存时遇到了问题。我知道解决方案,你在一个文件中读取数据,操纵它们,然后将它们写入另一个文件,但这对磁盘内存来说似乎效率低下。我知道,现在大多数人不会担心使用10gig的临时空间,但似乎应该有一种直接编辑文件夹头的方法。
答案 0 :(得分:5)
我的第一个想法是使用流解析器:基本上你一次读取一个文件并随时进行统计分析。这通常使用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
循环逐行浏览。但你还是要担心多行句子;另外,如果任何句子终结符不后跟一个空白字符,你必须插入换行符(而不是用它替换其他东西),这对于大文件来说可能是非常低效的。