Python:使用numpy或scipy读取Fortran二进制文件

4

我正在尝试读取一个包含整数头部和实际数据为32位浮点数的Fortran文件。使用numpy的fromfile('mydatafile', dtype=np.float32)可以将整个文件作为float32读入,但我需要将头部读入int32以便输出到我的文件中。使用scipy的FortranFile可以读取头部:

f = FortranFile('mydatafile', 'r')
headers = f.read_ints(dtype=np.int32)

但是当我执行以下操作时:

data = f.read_reals(dtype=np.float32)

它返回一个空数组。我知道它不应该是空的,因为使用numpy的fromfile可以读取所有数据。奇怪的是,scipy方法适用于我的数据集中的其他文件,但不适用于这个文件。也许我没有理解numpy和scipy两种读取方法之间的区别。在使用任一方法读取文件时,是否有一种方法可以隔离标头(dtype=np.int32)和数据(dtype=np.float32)?


1
如果您知道头文件的大小,那么读取所有内容为np.float32,然后将标题转换为整数如何? - Rain Lee
@RainLee 你如何使用int()函数进行转换?我刚刚找到了解决方案。我之前不知道可以使用np.fromfile逐行读取,所以现在我可以使用np.fromfile(fid, np.int32, 6)来读取前6行的整数,并且可以用np.fromfile(fid, np.float32, datalength)来读取数据。 - wxcoder
1
你可以将所有数据读取为 'float32',然后使用 data[:n].view(np.int32) 将对应于头部的部分转换为 np.int32 类型。其中 n 是头部元素的数量。 - rth
@rth 谢谢,这也非常好! - wxcoder
1
FortranFile 用于处理 Fortran 的“非格式化”二进制文件。尽管被称为“非格式化”,但这些文件将数据存储为记录,每个记录由一个标头指示的项目数,接着是项目数据本身,然后是第二份标头。另一方面,numpy.fromfile 用于处理没有任何尾部/标头的原始二进制数据。Fortran 也可以以此格式输出文件(取决于 OPEN 语句的参数)。因此,您需要知道您有哪种文件格式,并使用两种方法中的正确方法;使用错误的方法会导致错误的数据。 - pv.
2个回答

4

np.fromfile方法接受一个“count”参数,该参数指定要读取的项目数。如果您预先知道标题中整数的数量,则可以简单地将其作为整数读取,并将文件的其余部分作为浮点数读取,而无需进行任何类型转换:

with open('filepath','r') as f:
    header = np.fromfile(f, dtype=np.int, count=number_of_integers)
    data = np.fromfile(f, dtype=np.float32)

1

@DavidTrevelyan提供了一种相当不错的方法。另一种方法是使用fortranfile包结合struct使用。两种方法都不理想,但scipy的FortranFile也是如此。

至少这种方法可以读取混合类型数据。以下是一个例子:

from fortranfile import FortranFile
from struct import unpack

with FortranFile(to_open) as fh:
    dat = fh.readRecord()
    val_list = unpack('=4i20d'.format(ln), dat)

你可以使用 pip install fortranfile 进行安装。 struct 是标准的,(解)包格式在这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接