2017-12-20 1 views
1

python2でディレクトリ内の複数の.outファイルをクロールしてデータを抽出する比較的簡単なスクリプトを作成しようとしています。 データは識別子とともに.csvファイルに書き込まれます。python2スクリプトを使用して.csvファイルに書き込むときに、複数のファイルのデータに余分な文字( '。')が付加される

私の問題は、一見ランダムです。または '..'がデータ文字列の末尾に追加されます。ここで

が私のコードである(私は、これは事前に、見て恐ろしい申し訳ありません知っている):

import os 
import string 
import time 
import sys 
import csv 

input = raw_input 
location = input('Set directory path: ') 
os.makedirs(location+'/outputs/') 
print "Created output directory." 
print "Waiting for archiving to finish..." 
forCall = "cd "+location+" && mv *.out outputs/" 
os.system(forCall) 
time.sleep(1) 
print "Archived output files." 

newLocation = location+"/outputs/" 


def checker(filein, bondlength): 
    o = open("results.csv", "a") 
    with open(filein) as curFile: 
     for line in curFile: 
      if "SCF Done:" in line: 
       var = line 
       var = filter(lambda x: x.isdigit() or x == '-' or x == '.', var) 
       var = var[1:-2] # slices the first '-' and two trailing '.' 

       bondlength = ''.join(bondlength.split()) 
       bondlength = bondlength[:-4] # slices .out from 'bondlength.out' 
       o.write(var+';'+bondlength+'\n') 
    o.close() 

for filename in os.listdir(newLocation): 
    fileLocation = newLocation+filename 
    checker(fileLocation, filename) 

datacsv = csv.reader(open('results.csv'), delimiter=";") 
sortedData = sorted(datacsv, key=lambda row: row[1], reverse=False) 

with open('sortedData.csv', 'wb') as csv_file: 
    wr = csv.writer(csv_file, delimiter=";") 
    wr.writerows(sortedData) 

私はこのようなルックスに興味の.outファイル内の行:

SCF完了:E(RB + HF-LYP)= -107.450926197 AU 5サイクル後

ここで、各.outファイルに対して、Eの値(計算方法は問わない)を取得し、2つの列を持つ.csvファイルに追加する必要があります。ボンドの長さ(10^3を掛けましたが、今は関係ありません)。これは.outファイルの名前です(例1036.out)。

ご協力いただきまして誠にありがとうございます。

答えて

0

問題は、データを抽出するアプローチです - 例の行の数字、ダッシュまたはドット以外の文字を除外すると、--107.450926197..5になります。最初のダッシュはHF-LYPの部分から来て、後ろの5は5 cyclesとそれに先行する2つのドットはA.U.から来ます。部分文字列の最初と最後の文字をスライスすると、-107.450926197..が得られます。

私が代わりにお勧めしたいことは、あなたの文字列で=を発見してから次の空白文字まですべてを切り刻むことで数を見つけることです、のようなもの:

=
var = "SCF Done: E(RB+HF-LYP) = -107.450926197 A.U. after 5 cycles" 
var = var[var.find("=") + 1:].strip() # clean out everything before the equal sign 
var = var[:var.find(" ") + 1].strip() # clean out everything after the first whitespace 
# -107.450926197 

またはわずかにより危険な分割により、その後、スペース上:

var = "SCF Done: E(RB+HF-LYP) = -107.450926197 A.U. after 5 cycles" 
var = var.split("=", 1)[1].split(None, 1)[0] 
# -107.450926197 

または単純な正規表現でそれを行うには:

import re 

find_numbers = re.compile(r"-?[0-9]\d*(\.\d+)?") # find any number 

var = "SCF Done: E(RB+HF-LYP) = -107.450926197 A.U. after 5 cycles" 
var = find_numbers.search(var).group() 
# -107.450926197 

また、現在の結果をロードしてから、*.outファイルを繰り返し処理して同じリストに書き込み、そのリストをソートしてresults.csvを上書きすることを検討する必要があります。

+0

まずはご協力いただきありがとうございます。あなたの方法は間違いなくよりクリーンで簡単です。私はあなたが私の現在の結果を最初にロードすることについてあなたの最後の点で何を意味するか分かりません。明確にできますか? – cyphex

+0

@cyphex - 処理している '* .out'ファイルの' results.csv'を開いたり閉じたりして、最後まで読み込んで並べ替えて別のファイルに書き出すことができます。代わりに 'results.csv'を最初にロードし、メモリ内の行を読み込み、処理された' * .out'データをその行のリストに追加し、最後に '* .out 'ファイルを作成し、すべてを' results.csv'にそのまま書き出し、リストをソートし、ソートされたリストを 'sortedData.csv'に書き込みます。 – zwer

+0

もう一度、ありがとう! – cyphex

関連する問題