2011-06-23 11 views
0

私のPythonスクリプトに〜2GBのテキストファイル(約35Kファイル)をロードしようとしています。 page.read()の3分の1の周りにメモリエラーが発生します。私はPython MemoryErrorテキストファイルをロードする

for f in files: 
    page = open(f) 
    pageContent = page.read().replace('\n', '') 
    page.close() 

    cFile_list.append(pageContent) 

このサイズのオブジェクトやプロセスを決してPythonで処理したことはありません。他のPython MemoryError関連のスレッドをチェックしましたが、私のシナリオを修正するための何も得られませんでした。うまくいけば、そこに私を助けることができる何かがあります。

+3

あなたはチャンクで入力を読みたいと思うでしょう。この質問への答えを見てみましょう:http://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python –

+1

64ビットマシンを使用している場合は、 64ビットのPythonビルドを使用しています。 – geoffspear

+0

なぜ私はcFile_listのすべてのファイルのすべての内容を読み込んでいるのか分かりません。ファイルの内容と正確に何をしたいのですか? '\ n'を ''に置き換えて、それぞれのファイルの内容を別の対応するファイルに保存したいと思うかもしれません。これがあなたがやりたがっている場合は、その内容を新しいファイルに保存することができます。それはforループの中にあります。そして、あなたがこれを行うファイルの数にかかわらずメモリエラーは発生しません。 –

答えて

2

メモリにあまりにも多くを読み込もうとしています。これは、プロセスのサイズ制限(32ビットOSを中心に)が原因であるか、十分なRAMがないためです。

64ビットのOS(と64ビットのPython)は十分なRAMを与えられればOKですが、プログラムが動作している方法を変更するだけで、すべてのページが一度にRAMに入るわけではありません。

cFile_listとは何ですか?あなたは本当にメモリ内のすべてのページを同時に必要としますか?可能であれば

+0

cFile_listは大きな文書リストです。 Naive Bayes Classifierのトレーニングとテストセットになります。同時に何かをメモリに入れていない限り、何が変わるだろうか? – Greg

+1

@Greg、_filenames_をループするようにプログラムを変更できますか?各ファイル名について、ファイルを読み込み、ファイルをクリーンアップし、分類器にファイルを送り、ファイルを閉じます。この方法では、一度に1つのファイルしかramに入れる必要がありません。 –

1

はあなたのケースでは、発電機の使用を検討してください:

file_list = [] 
for file_ in files: 
    file_list.append(line.replace('\n', '') for line in open(file_)) 

file_listのは、今より多くのメモリ効率の高い文字列に、各ファイルの内容全体を読み込むよりもイテレータのリストです。すぐにfile_listのを反復処理することにより、Pythonでイテレータの性質のために一度だけ可能であること、しかし、あなたは

string_ = ''.join(file_list[i]) 

注を行うことができ、特定のファイルの文字列全体を必要とするES。

発電機の詳細については、http://www.python.org/dev/peps/pep-0289/を参照してください。

+0

ありがとうございました。すべてのファイルを読み込めましたが、結合しようとすると次のようになります。 ValueError:閉じたファイルの入出力操作 – Greg

+0

自分のフォールト:ファイルはwithのスコープの外側で閉じられます。私はコードを編集しました。また、ファイルを開くことが失敗しないように注意する必要があります。 – jena

0

メモリ内のファイル全体を読み取るには効果的ではありません。

正しい方法 - インデックスに慣れてください。

まず、各行の開始位置(キーは行番号、前の行の値を累積した長さ)で辞書を完成させる必要があります。 - 創業を行までファイルのプルーニングを実行するコマンド

def give_line(line_number): 
    t.seek(dict_pos.get(line_number)) 
    line = t.readline() 
    return line 

t.seek(LINE_NUMBER):

t = open(file,’r’) 
dict_pos = {} 

kolvo = 0 
length = 0 
for each in t: 
    dict_pos[kolvo] = length 
    length = length+len(each) 
    kolvo = kolvo+1 

、最終的には、機能を目指しています。したがって、次にreadlineをコミットすると、ターゲット行が取得されます。 このようなアプローチ(ファイル全体を実行せずにファイルの必要な位置に直接処理する)を使用すると、かなりの時間を節約でき、膨大なファイルを処理できます。

関連する問題