6

私はpythonが初めてで、ファイルからデータの「ブロック」を読み込もうとしています。ファイルは次のように書かれています。

# Some comment
# 4 cols of data --x,vx,vy,vz
# nsp, nskip =           2          10


#            0   0.0000000


#            1           4
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03


#            2           4
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03


#          500  0.99999422


#            1           4
 0.5057E+03  0.7392E-03 -0.6891E-03  0.4700E-02
 0.3777E+03  0.9129E-03  0.2653E-04  0.9641E-03
 0.2497E+03  0.9131E-03  0.7970E-04  0.8173E-03
 0.1217E+03  0.9131E-03  0.1378E-03  0.6586E-03

and so on

ここで、これらの多くのブロックから 1 つのデータ ブロックのみを指定して読み取ることができるようにしたいと考えています。データの読み取りに使用numpy.loadtxt('filename',comments='#')していますが、ファイル全体を一度にロードします。オンラインで検索したところ、誰かが numpy io ルーチンのパッチを作成して読み取りブロックを指定しましたが、主流の numpy にはありません。

gnuplot でデータのブロックを選択する方がはるかに簡単ですが、分布関数をプロットするルーチンを作成する必要があります。特定のブロックの読み取りを理解できれば、Python の方がはるかに簡単です。また、すべての視覚化コードを IDL と gnuplot から python に移行しているので、複数のパッケージに散らばっているのではなく、すべてを python に収めると便利です。

Python内からgnuplotを呼び出し、ブロックをテーブルにプロットし、出力をPythonの配列に割り当てることを考えました。しかし、私はまだ始めたばかりで、それを行うための構文を理解できませんでした。

この問題を解決するためのアイデア、指針は非常に役立ちます。

4

2 に答える 2

5

簡単な基本的な読み方:

>>> def read_blocks(input_file, i, j):
    empty_lines = 0
    blocks = []
    for line in open(input_file):
        # Check for empty/commented lines
        if not line or line.startswith('#'):
            # If 1st one: new block
            if empty_lines == 0:
                blocks.append([])
            empty_lines += 1
        # Non empty line: add line in current(last) block
        else:
            empty_lines = 0
            blocks[-1].append(line)
    return blocks[i:j + 1]

>>> for block in read_blocks(s, 1, 2):
    print '-> block'
    for line in block:
        print line


-> block
 0.5056E+03  0.8687E-03 -0.1202E-02  0.4652E-02
 0.3776E+03  0.8687E-03  0.1975E-04  0.9741E-03
 0.2496E+03  0.8687E-03  0.7894E-04  0.8334E-03
 0.1216E+03  0.8687E-03  0.1439E-03  0.6816E-03
-> block
 0.5057E+03  0.7392E-03 -0.6891E-03  0.4700E-02
 0.3777E+03  0.9129E-03  0.2653E-04  0.9641E-03
 0.2497E+03  0.9131E-03  0.7970E-04  0.8173E-03
 0.1217E+03  0.9131E-03  0.1378E-03  0.6586E-03
>>> 

これで、numpy を使用して行を読み取ることができると思います...

于 2012-05-09T17:23:57.517 に答える
1

次のコードは、おそらく開始する必要があります。おそらく re モジュールが必要になるでしょう。

次を使用して、読み取り用にファイルを開くことができます。

f = open("file_name_here")

を使用して、一度に 1 行ずつファイルを読み取ることができます。

line = f.readline()

「#」で始まる次の行にジャンプするには、次を使用できます。

while not line.startswith("#"):
    line = f.readline()

「# i j」のような行を解析するには、次の正規表現を使用できます。

is_match = re.match("#\s+(\d+)\s+(\d+)",line)
if is_match:
    i = is_match.group(1)
    j = is_match.group(2)

詳細については、「re」モジュールのドキュメントを参照してください。

ブロックを解析するには、次のコードを使用できます。

block = [[]] # block[i][j] will contain element i,j in your block
while not line.isspace(): # read until next blank line
    block.append(map(float,line.split(" "))) 
    # splits each line at each space and turns all elements to float
    line = f.readline()

必要に応じて、ブロックを numpy 配列に変換できます。

block = np.array(block)

numpy を np としてインポートした場合。i と j の間の複数のブロックを読み取りたい場合は、上記のコードを配置して、1 つのブロックを関数に読み取り、それを複数回使用します。

お役に立てれば!

于 2012-05-09T17:05:03.927 に答える