2016-05-30 3 views
2

以下のFortranコードからバイナリファイル出力を読み込もうとしていますが、結果は出力ファイルと同じではありません。Python Fortranバイナリファイルを読む

Fortran 77のコード:

program test 
    implicit none 
    integer i,j,k,l 
    real*4  pcp(2,3,4) 
    open(10, file='pcp.bin', form='unformatted') 
    l = 0 
    do i=1,2 
     do j=1,2 
     do k=1,2 
      print*,k+l*2 
      pcp(i,j,k)=k+l*2 
      l = l + 1 
     enddo 
     enddo 
    enddo 
    do k=1,4 
     write(10)pcp(:,:,k) 
    enddo 
    close(10) 
    stop 
    end 

私は以下のPythonコードを使用しようとしている:

from scipy.io import FortranFile 
f = FortranFile('pcp.bin', 'r') 
a = f.read_reals(dtype=float) 
print(a) 
+0

「[Pythonで直接アクセスするFortranフォーマットされていないファイルを読む]」の複製があります(http://stackoverflow.com/questions/10475839/reading-a-direct-access-fortran-unformatted-file-in-python) –

+0

可能[Python:numpyやscipyを使ってFortranバイナリファイルを読む]の複製(http://stackoverflow.com/questions/30307305/python-reading-fortran-binary-file-using-numpy-or-scipy) – glls

+0

ありがとう私は両方の解決策を試みます。私のFortranコードでは、3つの変数と実際の* 4の精度があります。 – marcelorodrigues

答えて

2

、単に(read_realsにdtype='float32'(またはdtype=np.float32)にdtype=floatを交換してください) :

>>> from scipy.io import FortranFile 
>>> f = FortranFile('pcp.bin', 'r') 
>>> print(f.read_reals(dtype='float32')) 
[ 1. 9. 5. 13. 0. 0.] 
>>> print(f.read_reals(dtype='float32')) 
[ 4. 12. 8. 16. 0. 0.] 
>>> print(f.read_reals(dtype='float32')) 
[ 0. 0. 0. 0. 0. 0.] 
>>> print(f.read_reals(dtype='float32')) 
[ 0. 0. 0. 0. 0. 0.] 

得られたデータはそれぞれ0 Fortranでは、としては、(ゼロに初期化pcp付き)を与える

do k=1,4 
    print "(6f8.3)", pcp(:,:,k) 
enddo 

1.0 9.0 5.0 13.0 0.0 0.0 
    4.0 12.0 8.0 16.0 0.0 0.0 
    0.0 0.0 0.0 0.0 0.0 0.0 
    0.0 0.0 0.0 0.0 0.0 0.0 

によって検証しかし>>> help(FortranFile)ので

Fortranで書式なしシーケンシャル・ファイルの例を言うだろう次のように書かれている:

OPEN(1, FILE=myfilename, FORM='unformatted')

WRITE(1) myvariable

これは、その内容が コンパイラに依存し、マシンのエンディアン、注意が助言される非標準のファイル形式であるため。 のファイル、gfortran 4.8.0、およびx86_64のgfortran 4.1.2が動作することが知られています。

新しいストリームの I/OのFortranダイレクトアクセスファイルまたはファイルを使用することを検討してください。これは簡単にnumpy.fromfileで読むことができます。

場合によってはnumpy.fromfile()を使用する方が簡単かもしれません(StanleyRの答えに示されています)。

1

使用nupy.fromfile(http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html

は、私はあなたが何かを見逃していると思いますFortranコードでバイナリファイルに書き込むには、次のコードを適用します。

program test 
implicit none 
integer i,j,k,l, reclen 
real*4  pcp(2,3,4) 

inquire(iolength=reclen)pcp(:,:,1) 
open(10, file='pcp.bin', form='unformatted', access = 'direct', recl = reclen) 
pcp = 0 
l = 0 
do i=1,2 
do j=1,2 
do k=1,2 
    print*,i,j,k,k+l*2 
    pcp(i,j,k)=k+l*2 
    l = l + 1 
enddo 
enddo 
enddo 
do k=1,4 
    write(10, rec=k)pcp(:,:,k) 
enddo 
close(10) 
end 

は、Pythonでファイルを読み込むには:

import numpy as np 
with open('pcp.bin','rb') as f: 
    for k in xrange(4): 
     data = np.fromfile(f, dtype=np.float32, count = 2*3) 
     print np.reshape(data,(2,3)) 

出力:あなたはシーケンシャルファイルにreal*4データを書き込んでいるので

[[ 1. 9. 5.] 
[ 13. 0. 0.]] 
[[ 4. 12. 8.] 
[ 16. 0. 0.]] 
[[ 0. 0. 0.] 
[ 0. 0. 0.]] 
[[ 0. 0. 0.] 
[ 0. 0. 0.]] 
+2

あなたの答えは、「出力ではなく、直接的なアクセスを使用するようにFortranプログラムを変更する必要があります」と表示されます。それが意図(重要な変更)であれば、おそらくそれについてもっと明白である方がよいでしょうか? – francescalus

関連する問題