3

Fortran77で記述された単精度のリトルエンディアンのフォーマットされていないデータファイルがいくつかあります。次のコマンドを使用してPythonを使用してこれらのファイルを読み取っています。

import numpy as np
original_data = np.dtype('float32')
f = open(file_name,'rb')                                                                                                 
original_data = np.fromfile(f,dtype='float32',count=-1)                                                                            
f.close()

Pythonでデータを操作した後、次のコマンドを使用してPythonを使用して元の形式でデータを書き戻します。

out_file = open(output_file,"wb")                                                                                             
s = struct.pack('f'*len(manipulated_data), *manipulated_data)                                                                     
out_file.write(s)
out_file.close()

しかし、それは機能していないようです。Pythonを使用して元のFortranのフォーマットされていない形式でデータを書き戻す正しい方法は何ですか?

問題の詳細:

Fortranからの操作データを含む最終ファイルを読み取ることができます。ただし、ソフトウェア(Paraview)を使用してこれらのデータを視覚化したいと思います。このために、フォーマットされていないデータファイルを*h5フォーマットに変換します。h5ユーティリティを使用して、元のデータと操作されたデータの両方をh5形式に変換できます。ただし、Paraviewは元のデータから作成された* h5ファイルを読み取ることはできますが、Paraviewは操作されたデータから作成された*h5ファイルを読み取ることはできません。翻訳で何かが失われていると思います。

これは、PythonによってFortranで記述されたファイル(単精度データ)を開く方法です。

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

そして、これは私がFortranによって元のフォーマットされていないデータを書いていることです:

open(out_file_id,FILE=out_file,form="unformatted")

この情報で十分ですか?

4

2 に答える 2

2

これは、フォーマットされていないシーケンシャル アクセス ファイルを作成しています。

open(out_file_id,FILE=out_file,form="unformatted")

real a(n,n,n)単純に使用して単一の配列を作成していると仮定するとwrite(out_file_id)a、ファイルサイズは 4*n^3+8 バイトになります。余分な 8 バイトは、4 バイトの整数 (=4n^3) であり、レコードの先頭と末尾で繰り返されます。

2 番目の形式:

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

これらのヘッダーを持たない直接アクセスを開きます。今書くために、あなたは持っているでしょうwrite(unit,rec=1)aダイレクトアクセスを使用してシーケンシャルアクセスファイルを読み取ると、エラーなしで読み取られますが、整数ヘッダーが (1,1,1) 配列値として float (ガベージ) として読み取られ、他のすべてがシフトされます。あなたは fortran で読むことができると言っていますが、本当にあなたが期待しているものを読んでいるかどうかを確認したいですか?

これに対する最善の解決策は、元の Fortran コードを修正して、読み取りと書き込みの両方に書式なしの直接アクセスを使用することです。これにより、ヘッダーのない「通常の」生のバイナリ ファイルが得られます。

あるいは、Python で最初にその 4 バイト整数を読み取り、次にデータを読み取る必要があります。出力では、paraview フィルターが何を期待しているかに応じて、整数ヘッダーを戻すかどうかを指定できます。

---------- これは、単一のレコードを含むフォーマットされていない順次 fortran ファイルを読み取り/変更/書き込みするための python です。

import struct
import numpy as np
f=open('infile','rb')
recl=struct.unpack('i',f.read(4))[0]
numval=recl/np.dtype('float32').itemsize
data=np.fromfile(f,dtype='float32',count=numval)
endrec=struct.unpack('i',f.read(4))[0]
if endrec is not recl: print "error unexpected end rec"
f.close()
f=open('outfile') 
f.write(struct.pack('i',recl))
for i in range(0,len(data)):data[i] = data[i]**2  #example data modification
data.tofile(f)
f.write(struct.pack('i',recl)

複数のレコードをループするだけです。ここのデータはベクトルとして読み取られ、すべて浮動小数点数であると想定されることに注意してください。もちろん、使用する場合は実際のデータ型を知る必要があります。また、プラットフォームによってはバイト順の問題に対処する必要がある場合があることに注意してください。

于 2013-02-25T16:37:59.773 に答える
2

加工データ配列の .tofile メソッドを使ってみましたか?C オーダーで配列を書き込みますが、プレーン バイナリを書き込むことができます。

.tofile のドキュメントも、これが次と同じであることを示唆しています。

with open(outfile, 'wb') as fout:
    fout.write(manipulated_data.tostring())
于 2013-02-21T16:20:59.390 に答える