2016-05-30 223 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:阅读Fortran二进制文件使用numpy或scipy](http://stackoverflow.com/questions/30307305/python-reading-fortran-binary-file-using-numpy-or-scipy) – glls

+0

谢谢你们,但我尝试两种解决方案。在我的Fortran代码中有一个3d变量和真正的* 4精度。 – marcelorodrigues

回答

2

因为你在一个连续的文件中写入real*4数据,只是一味在read_reals更换dtype=floatdtype='float32'(或dtype=np.float32)() :

>>> 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语言,如验证通过

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

这给(与pcp初始化为零)

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

由于这是一个非标准的文件格式,其内容取决于 编译器和机器的字节顺序,谨慎建议。来自 的文件知道x86_64上的gfortran 4.8.0和gfortran 4.1.2可以正常工作。

考虑使用Fortran直接访问文件或来自较新Stream I/O的文件,这些文件可以通过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 

要由蟒蛇读文件:

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)) 

输出:

[[ 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