2017-02-24 16 views
0

モデルの出力ファイルを連結しようとしていますが、モデルの実行は5で分割されており、それぞれの出力はソフトウェアの出力方法各ファイル出力で0から再ラベル付けを開始します。メモリエラーPython大ファイルの行ごとの処理

2)結合されたファイルを編集してすべてのタイムステップを再ラベル付けします.0から始まり、それぞれのインクリメントで増加します。

目的は、5つの異なるウィンドウを開くのではなく、この単一のファイルを1つのチャンク内の視覚化ソフトウェアに読み込むことです。

これまでのところ私のコードは、私が扱っている大きなファイルのためにメモリエラーをスローします。

私はどのようにしてそれを取り除くことができるかについてのいくつかのアイデアを持っていますが、何がうまくいくか、クロールに遅くなるかもしれません。

コードは、これまで:

import os 
import time 

start_time = time.time() 

#create new txt file in smae folder as python script 

open("domain.txt","w").close() 


"""create concatenated document of all tecplot output files""" 
#look into file number 1 

for folder in range(1,6,1): 
    folder = str(folder) 
    for name in os.listdir(folder): 
     if "domain" in name: 
      with open(folder+'/'+name) as file_content_list: 
       start = "" 
       for line in file_content_list: 
        start = start + line# + '\n' 
       with open('domain.txt','a') as f: 
        f.write(start) 
       # print start 

#identify file with "domain" in name 
#extract contents 
#append to the end of the new document with "domain" in folder level above 
#once completed, add 1 to the file number previously searched and do again 
#keep going until no more files with a higher number exist 

""" replace the old timesteps with new timesteps """ 
#open folder named domain.txt 
#Look for lines: 
##ZONE T="0.000000000000e+00s", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL 
##STRANDID=1, SOLUTIONTIME=0.000000000000e+00 
# if they are found edits them, otherwise copy the line without alteration 

with open("domain.txt", "r") as combined_output: 
    start = "" 
    start_timestep = 0 
    time_increment = 3.154e10 
    for line in combined_output: 
     if "ZONE" in line: 
      start = start + 'ZONE T="' + str(start_timestep) + 's", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL' + '\n' 
     elif "STRANDID" in line: 
      start = start + 'STRANDID=1, SOLUTIONTIME=' + str(start_timestep) + '\n' 
      start_timestep = start_timestep + time_increment 
     else: 
      start = start + line 

    with open('domain_final.txt','w') as f: 
     f.write(start) 

end_time = time.time() 
print 'runtime : ', end_time-start_time 

os.remove("domain.txt") 

これまでのところ、私は連結段階でのメモリエラーを取得します。

1)試してみて、私はそれぞれのファイルを読み込むと、外出先での補正を行うが、まだ全体の1を通過に失敗していますので、私はそれがはるかになるだろうとは思わない:

は、私は可能性が改善するため、時間

2)の計算以外の違いは、配列にように、すべてのファイルをロードし、チェックの機能を作り、アレイ上にその機能を実行します。

のような何か:

def do_correction(line): 
     if "ZONE" in line: 
      return 'ZONE T="' + str(start_timestep) + 's", N=87715, E=173528, F=FEPOINT, ET=QUADRILATERAL' + '\n' 
     elif "STRANDID" in line: 
      return 'STRANDID=1, SOLUTIONTIME=' + str(start_timestep) + '\n' 
     else: 
      return line 

3)それをそのままにして、メモリが不足していることをPythonに指示して、その段階でファイルに書き込みます。それが可能なら誰でも知っていますか?

は、出力ファイルに書き込む前にメモリに各ファイルの内容全体をリードする必要はありませんあなたの助け

+1

私は、あなたが最後ではなく、オンザフライでデータを書かない理由を知りません。これはストリームに準拠しています(注:文字列の連結のために年数がかかる)。コードを完全に書き直す必要があります。 –

+1

forループの前に出力を開いて、各行の結果を出力ファイルに直接書き込んでください。そうでなければ、あなたの "start"変数は非常に大きなファイルで爆発します。 – MKesper

+0

ファイルへの書き込みはコストのかかる操作なので、すべてを1つの文字列にスタックし、最後にこの文字列を1つのwrite()ステートメントで書きたいと思っていました。あなたのコメントから、私は各行でf.write()を持つ方が速いことを知ります。 – Sorade

答えて

2

、ありがとうございました。大容量のファイルは、使用可能なすべてのメモリを消費します。

一度に1行ずつ読み書きしてください。出力ファイルを1回だけ開くだけで、ピックアップされずに入力ファイルとして扱われる名前を選択します。そうしないと、出力ファイルを連結する危険性があります(問題はありませんがif現在のディレクトリからのファイルも処理します) - ロードすると、すべてのメモリを消費していません。

import os.path 

with open('output.txt', 'w') as outfile: 
    for folder in range(1,6,1): 
     for name in os.listdir(folder): 
      if "domain" in name: 
       with open(os.path.join(str(folder), name)) as file_content_list: 
        for line in file_content_list: 
         # perform corrections/modifications to line here 
         outfile.write(line) 

これで、データを行指向の方法で処理できます。出力ファイルに書き込む前に変更するだけです。

関連する問題