Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python读写大文件_Python_File_Text_Io_Python 3.5 - Fatal编程技术网

用python读写大文件

用python读写大文件,python,file,text,io,python-3.5,Python,File,Text,Io,Python 3.5,我有一个大的.txt文件,超过24000000行。现在我想做一个单词计数,也就是说,计算每个单词及其对应的出现次数,并将它们记录到一个新文件中。以下是我尝试运行的代码: import gensim class Corpus(gensim.corpora.TextCorpus): def count_tokens(self): word_count = 0 for text in self.get_texts(): word_cou

我有一个大的
.txt
文件,超过24000000行。现在我想做一个单词计数,也就是说,计算每个单词及其对应的出现次数,并将它们记录到一个新文件中。以下是我尝试运行的代码:

import gensim
class Corpus(gensim.corpora.TextCorpus): 
    def count_tokens(self):
        word_count = 0
        for text in self.get_texts():
            word_count += len(text)
        return word_count
    def get_texts(self): 
        for filename in self.input: 
            yield open(filename).read().split()

def main():
    corpus = Corpus(['somefile.txt'])
    word_count = corpus.count_tokens()
    text = open('somefile.txt').read().split()
    with open('path_to_output', 'w') as f:
        for word, _ in corpus.dictionary.token2id.items():
            num_occur = text.count(word)
            f.write('%s %d\n' % (word, num_occur))

if __name__  == '__main__':
    main()

服务器挂起。。。我想知道是否有其他足够的方法来做到这一点,或者我能做些什么改进?如何使用python读写真正大的文件?

我会这样做:

words = {}
with open('somefile.txt', 'r') as textf:
    for line in textf.readlines():
        for word in line.split():
            words[word] = words.getdefault(word, 0) + 1
不是很像python,但它的想法是,您的
获取文本()
方法一次读取内存中的整个文件。对于有很多小文件的语料库来说,这很好,但是如果你有一个大文件,你需要逐行阅读

from collections import Counter
wordcounts = Counter()

with open("file.txt") as fp:
    for line in fp:
        wordcounts.update(line.split())

您的代码有许多问题:

  • 它读取内存中的文件,然后拆分单词,从而将内存大小增加一倍(或三倍)
  • 它会这样做两次,首先计算单词的数量,然后计算每个单词的出现次数
我创建了一个简单的示例,没有您的对象和所有对象,在几个文件上使用
collections.Counter
<代码>文本文件列表保存文件路径列表

import collections

c = collections.Counter()
for text_file in text_file_list:
   with open(text_file) as f:
       c.update(word for line in f for word in line.split())

在文件上循环,并更新每个文件的专用
计数器
字典。文件是逐行读取的,永远不会完全读取。因此它需要一些时间,但不会占用太多内存。

使用类似system-parse char的标记器,并检查匹配项。当不明确时,继续查看下一个字符,以确定是否有一个连续的
打开(filename).read().split()
完全读取文件,然后创建一个标记化版本:同时增加两倍内存。如果只需要计数,Uriel方法可能是正确的。如果文件只是一长串单词,会发生什么?如果文件足够大,这仍然是一个问题,这个方法可以在几分钟内完成!拯救我的一天!谢谢@乌里尔,每行一个字的效果是一样的。只有在文件中没有换行符时才会出现问题。在这种情况下,您需要读取字节块,并修复损坏的字,甚至边缘损坏的多字节字符。很明显,插入一个可以做到这一点的库会更容易。但很明显,这是一个文本文件,即换行符,所以不需要去那里。@alexis,这就是我的意思,一个用空格分隔的列表。但从OP的评论来看,情况并非如此。在这种情况下,回答得很好。对于没有换行符的文件,nltk的语料库读取器由一个“流读取器”支持,该“流读取器”实现了我所描述的功能。Gensim可能也会这样做(我不使用它),但OP绕过了它的文件I/o。无论如何,OP的问题是关于一个超过2400万行的文件。这不会有帮助,它仍然会一次读取内存中的整个文件。但是将
替换为text中的行f.readlines():
应该更好。它一次只能读取一行,不需要其他更改。也可以使用
集合。计数器
会更好。