2016-06-20 6 views
1

私はちょうど私の最初の研究プロジェクトを始めました。私はプログラミングを始めました(約2週間前)。私の質問が素朴であれば、すみません。私は非常に非効率的にPythonを使用している可能性があります。私はここで改善することを切望しています。Python:複雑なディレクトリツリー内のファイルから浮動小数点数を抽出する - ループは答えですか?

私は分析したい実験データがあります。私の目標は、入力としてデータを取るpythonスクリプトを作成することです。出力には、テキストファイル(実験データフォルダ内の)に含まれる特定のパラメータがプロットされ、特定の方程式に適合するグラフが表示されます。このスクリプトはできるだけ一般化して他の実験にも使えるようにする必要があります。

私はAnaconda、Python 2.7パッケージを使用しています。これは、科学と数学に関連するさまざまなライブラリ/モジュールにアクセスできることを意味します。

ForループとWhileループを使用しようとしています(初めて)。私が何をしたいか

.../data/B_foo[1-7]/[1-6]/D_foo/E_foo/text.txt 

はすべて7トップディレクトリをサイクルにあり、その6つの各サブディレクトリ(1命名:

データファイルは、この(私はここに正規表現ブラケットを使用しています)のように構成されています、2,3 ... 6)。さらに、これらの6つのサブディレクトリには、アクセスしたいデータを含むテキストファイル(常に同じファイル名、text.txt)があります。

1  91.146 4.571 0.064 1.393 939.134  14.765 

2  88.171 5.760 0.454 0.029 25227.999 137.883 

3  88.231 4.919 0.232 0.026 34994.013 247.058 

4  ...  ...  ...  ...  ...   ... 

テーブルがダウンし続けて:

'TEXT.TXT' ファイルは、このようなものを構成されています。他のすべての行は空です。私は8行目から13行目から情報を取り出したいと思います.2列目、3列目、5列目にしか興味がありません。私はそれらをそれぞれ 'parameter_a'と 'parameter_b'と 'parameter_c'というリストに入れたいと思います。私は、これらの 'text.txt'ファイル(合計7 * 6 = 42)からこれらのファイルを作成し、3つの大きなリスト(それぞれ合計7 * 6 * 13 = 546すべてが完了したときのアイテム)。

これは私の試みです:

まず、私は、リストを作った「list_B_foo」、(スクリプトのこの部分は示されていない)7つの異なる「B_foo」ディレクトリを含みます。私はそれが動作するように取得せずにインデントと周りいじるしようとしてい

parameter_a = [] 
parameter_b = [] 
parameter_c = [] 
j = 7 # The script starts reading 'text.txt' after the j:th line. 
k = 35 # The script stops reading 'text.txt' after the k:th line. 
x = 0 
while x < 7: 
    for i in range(1, 7): 
     path = str(list_B_foo[x]) + '/%s/D_foo/E_foo/text.txt' % i 
     m = open(path, 'r') 
     line = m.readlines() 
     while j < k: 
      line = line[j] 
      info = line.split() 
      print 'info:', info 
      parameter_a.append(float(info[1])) 
      parameter_b.append(float(info[2])) 
      parameter_c.append(float(info[5])) 
      j = j + 2 
    x = x + 1 

parameter_a_vect = np.array(parameter_a) 
parameter_b_vect = np.array(parameter_b) 
parameter_c_vect = np.array(parameter_c) 

print 'a_vect:', parameter_a_vect 
print 'b_vect:', parameter_b_vect 
print 'c_vect:', parameter_c_vect 

(構文エラーやインデントのいずれかのエラー受け):それから私はこれを作りました。現在、私はこの出力を得る:

info: ['1', '90.647', '4.349', '0.252', '0.033', '93067.188', '196.142'] 
info: ['.'] 
Traceback (most recent call last): 
    File "script.py", line 104, in <module> 
    parameter_a.append(float(info[1])) 
IndexError: list index out of range 

私は「リストのインデックス範囲外」というメッセージが表示されますなぜ私は理解していません。なぜこれが当てはまるか知っていれば、私はあなたを聞いてうれしいです。

この問題を解決するにはどうすればよいですか?私のアプローチは完全に間違っていますか?

EDIT:私はRebelWithoutAPulseとCamJohnson26の提案を考慮して、純粋なwhileループソリューションを探しました。これは私がそれを解決する方法である:

parameter_a=[] 
parameter_b=[] 
parameter_c=[] 
k=35 # The script stops reading 'text.txt' after the k:th line. 
x=0 
while x < 7: 
    y=1 
    while y < 7: 
     j=7 
     path1 = str(list_B_foo[x]) + '/%s/pdata/999/dcon2dpeaks.txt' % (y) 
     m = open(path, 'r') 
     lines = m.readlines() 
     while j < k: 
      line = lines[j] 
      info = line.split() 
      parameter_a.append(float(info[1])) 
      parameter_b.append(float(info[2])) 
      parameter_c.append(float(info[5])) 
      j = j+2 
     y = y+1 
    x = x+1 

メタ:私は最速答えたと私は私の仕事を終える助けた人に答えを与える必要がある場合はわかりません。または、私が最も学んだ答えを持つ人。私はルールを読んだり、Stackexchange Metaに行くことで答えが見つかるという共通の問題だと確信しています。私が勧告を読んでみるまで、私はあなたの2人が答えたように印をつけます。

答えて

1

ようこそ、スタックオーバーフロー!

エラーは、あなたが不注意に作成した名前の衝突によるものです。例外が発生する前に出力に注意してください。

info: ['1', '90.647', '4.349', '0.252', '0.033', '93067.188', '196.142'] 
info: ['.'] 
Traceback (most recent call last): 
... 

ライン[1]を計算することができない - だけ'.'を含むリストには「1」-st要素は存在しない - Pythonでリストが0の位置で開始します。

これはあなたのネストされたループ内で起こる、あなたが再定義

while j < k 

非常に line以前に作成された読み取り:

line = m.readlines() 
    while j < k: 
     line = line[j] 
     info = line.split() 
     ... 

だから、何が起こるか、あなたの読み、ループの最初の実行でありますファイルの行をline listに追加した後、リストから1行を取り出し、それをlineに再度割り当て、ループを続行します。この時点でlineにはの文字列が含まれています。

lineから指定されたインデックスを読み取ると、j番目の文字列の文字が読み取られ、コードが誤動作します。

これを別の名前で修正できます。

P.S.ファイルを扱うときにwith ... as ...の構文を使用することをお勧めします。簡潔にはhereと記載されています。これはコンテキストマネージャと呼ばれ、ファイルを開いたり閉じたりします。

P.P.S.私も読むことをお勧めしますnaming conventions

+0

本当にお返事ありがとうございました。とても有難い。私の専門知識と知識のレベルを考慮に入れて、とても良い提案です。私は命名規則を素早く見て、それらを学ぶことは良い選択であると思っています。私は時間があれば、間違いなくそれらに戻るでしょう。 PS:元の質問の編集内容を読んでください。 – Lucubrator

1

ファイルの最初の行で行配列を上書きしているようです。 line = m.readlines()を呼び出すと、行を行の配列に等しく設定します。あなたはそのようになりましたライン変数は、もはや配列である、それは

1  91.146 4.571 0.064 1.393 939.134  14.765 

に等しい文字列です。このループは正常に動作しますが、次のループは、文字の配列として行を扱います、line =行[j]を設定します単なる期間である第4要素を取って、それ自体と同じに設定します。これは、info変数がループを2回通過する際に1つの要素しか持たない理由を説明しています。

これを解決するには、1つではなく2つの行変数を使用してください。 1行ともう1行を呼び出します。

lines = m.readlines() 
    while j < k: 
     line = lines[j] 
     info = line.split() 

他のエラーもあるかもしれませんが、それはあなたを始められるはずです。

+0

ありがとう、これは助けた。今私は誤りがない。不思議にも、スクリプトは最初の 'text.txt'(.../data/B_foo1/1/D_foo/E_foo/textにある)を通過するようにしか見えません。TXT)、そして私はこのようなリスト/配列の長さを印刷する場合: プリント「c_vectの長さ:」、LEN(parameter_c_vect) を私はこれを取得:c_vectの 長さ:13 私が見れますこれ以上明日。ご協力ありがとうございました!非常に明確な答え。 – Lucubrator

+0

ええ、簡単に修正するだけで、各パスでj変数をリセットする必要があります。 j = 7行をwhile文のすぐ下に移動します。私がそれを感謝する答えとしてマークすることができたら助けてうれしい! – CamJohnson26

関連する問題