我使用Fortran创建一个包含多行的二进制文件:
Program write_binary
implicit none
integer i
real x
open(10,file="test.dat",form="unformatted")
do i=1,10
write(10),i*1.0,i*2.0
end do
close(10)
end
然后我使用Python,尝试读取整个文件。但是,FortranFile包只能逐行读取(请参见下面的代码)。有什么办法可以读取Fortran创建的二进制文件的所有行?非常感谢。
from scipy.io import FortranFile
import numpy as np
f=FortranFile('test.dat','r')
x=read_reals(dtype='f4')
print(x)
答案 0 :(得分:1)
我经常用Fortran编写数据并用Python读取数据。我将在这里针对多个3D阵列的情况进行解释,因为它更通用并且更容易适应1D阵列。
在Fortran中,我使用以下循环编写数据:
file = 'my_fortran_data.dat'
open(99, file=file, status = 'replace', action = 'write', form = 'unformatted', access='stream')
do k = 1,L
do j = 1,M
do i = 1,N
write(99) u(i,j,k), v(i,j,k), w(i,j,k)
end do
end do
end do
close(99)
请注意,我将数据写入stream
访问中。因此,我不会记录每个记录的开头和结尾(使文件变小)。
我从Python使用以下函数读取以下数据:
def read_data(file, dtype, stream):
"""
Return the components of a 3D vector field stored in binary format.
The data field is supposed to have been written as: (for k; for j; for i;) where the last dimension
is the quickest varying index. Each record should have been written as: u, v, w.
The returned components are always converted in np.double precision type.
Args:
dim: number of dimensions
dtype: numpy dtype object. Single or double precision expected.
stream: type of access of the binary output. If true, the file can only contain data.
If false, there is a 4-byte header and footer around each "record"
in the binary file (can happen in some Fortran compilers if access != 'stream').
"""
if stream:
shape = (L, M, N, 3)
f = open(file, 'rb')
data = np.fromfile(file=f, dtype=dtype).reshape(shape)
f.close()
u = data[:, :, :, 0].transpose(2, 1, 0)
v = data[:, :, :, 1].transpose(2, 1, 0)
w = data[:, :, :, 2].transpose(2, 1, 0)
del data
else:
shape = (L, M, N, 5)
f = open(file, 'rb')
data = np.fromfile(file=f, dtype=dtype).reshape(shape)
f.close()
u = data[:, :, :, 1].transpose(2, 1, 0)
v = data[:, :, :, 2].transpose(2, 1, 0)
w = data[:, :, :, 3].transpose(2, 1, 0)
del data
u = u.astype(np.float64, copy=False)
v = v.astype(np.float64, copy=False)
w = w.astype(np.float64, copy=False)
return(u, v, w)
请注意,我总是将数据转换为双精度,但是如果不需要,您可以省略最后一步。
根据您的情况,对shape=(10,2)
访问使用stream
,否则使用shape=(10,4)
。