我在用 Python 读取未格式化的 F77 二进制文件时遇到问题。
我已经尝试过SciPy.io.FortraFile
方法和NumPy.fromfile
方法,均无济于事。我还阅读了 IDL 中的文件,该文件有效,因此我对数据应该是什么样子有了一个基准。我希望有人能指出我的一个愚蠢的错误——没有什么比有一个白痴时刻然后洗手更好的了......
数据 bcube1 的尺寸为 101x101x101x3,且为 r*8 类型。总共有 3090903 个条目。它们是使用以下语句编写的(不是我的代码,从源代码复制)。
open (unit=21, file=bendnm, status='new'
. ,form='unformatted')
write (21) bcube1
close (unit=21)
我可以使用以下代码在 IDL 中成功读取它(也不是我的代码,是从同事那里复制的):
bcube=dblarr(101,101,101,3)
openr,lun,'bcube.0000000',/get_lun,/f77_unformatted,/swap_if_little_endian
readu,lun,bcube
free_lun,lun
返回的数据 (bcube) 是双精度的,尺寸为 101x101x101x3,因此文件的标头信息知道其尺寸(而不是展平)。
现在我尝试使用 Python 获得相同的效果,但没有成功。我尝试过以下方法。
In [30]: f = scipy.io.FortranFile('bcube.0000000', header_dtype='uint32')
In [31]: b = f.read_record(dtype='float64')
返回错误Size obtained (3092150529) is not a multiple of the dtypes given (8)
。更改 dtype 会更改获得的大小,但它仍然不能被 8 整除。
或者,使用fromfile
结果没有错误,但返回数组中的另一个值(也许是页脚?),并且各个数组值都非常错误(应该全部具有统一的顺序)。
In [38]: f = np.fromfile('bcube.0000000')
In [39]: f.shape
Out[39]: (3090904,)
In [42]: f
Out[42]: array([ -3.09179121e-030, 4.97284231e-020, -1.06514594e+299, ...,
8.97359707e-029, 6.79921640e-316, -1.79102266e-037])
我尝试使用 byteswap 来查看这是否使浮点值更合理,但事实并非如此。
在我看来,np.fromfile
方法非常接近工作,但它读取标题信息的方式一定有问题。谁能建议我如何弄清楚什么should位于允许 IDL 了解数组维度和数据类型的头文件中吗?有没有办法将标头信息传递给fromfile
这样它就知道如何处理领先的条目?