3

我有一些由 Fortran77 编写的单精度 little-endian 无格式数据文件。我正在使用 Python 使用以下命令读取这些文件:

import numpy as np
original_data = np.dtype('float32')
f = open(file_name,'rb')                                                                                                 
original_data = np.fromfile(f,dtype='float32',count=-1)                                                                            
f.close()

在 Python 中进行一些数据操作后,我(正在尝试)使用 Python 使用以下命令将它们以原始格式写回:

out_file = open(output_file,"wb")                                                                                             
s = struct.pack('f'*len(manipulated_data), *manipulated_data)                                                                     
out_file.write(s)
out_file.close()

但这似乎不起作用。任何想法使用 Python 以原始 fortran 未格式化格式写回数据的正确方法是什么?

问题详情:

我能够使用来自 Fortran 的操作数据读取最终文件。但是,我想使用软件(Paraview)可视化这些数据。为此,我将未格式化的数据文件转换为 *h5 格式。我能够使用 h5 实用程序将原始数据和操作数据转换为 h5 格式。但是,虽然 Paraview 能够读取从原始数据创建的 *h5 文件,但 Paraview 无法读取从操纵数据创建的 *h5 文件。我猜有些东西在翻译中丢失了。

这就是我在 Fortran 中打开由 Python 编写的文件的方式(单精度数据):

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

这是我正在用 Fortran 编写原始的未格式化数据:

open(out_file_id,FILE=out_file,form="unformatted")

这些信息是否足够?

4

2 回答 2

2

您是否尝试过使用操作数据数组的 .tofile 方法?它将按 C 顺序写入数组,但能够写入普通二进制文件。

.tofile 的文档也表明这与以下内容相同:

with open(outfile, 'wb') as fout:
    fout.write(manipulated_data.tostring())
于 2013-02-21T16:20:59.390 回答
2

这是创建一个未格式化的顺序访问文件:

open(out_file_id,FILE=out_file,form="unformatted")

假设您正在编写一个real a(n,n,n)简单的数组,write(out_file_id)a您应该会看到文件大小为 4*n^3+8 字节。额外的 8 个字节是一个 4 字节整数 (=4n^3),在记录的开头和结尾重复。

第二种形式:

open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*n*n*n)

打开没有这些标题的直接访问。对于现在写作,您将拥有write(unit,rec=1)a. 如果您使用直接访问读取顺序访问文件,它将无错误地读取,但您会将该整数标头读取为浮点数(垃圾)作为 (1,1,1) 数组值,然后其他所有内容都会移位。你说你可以用 fortran 阅读,但你是否希望看到你真的在阅读你所期望的?

对此的最佳解决方法是修复您的原始 fortran 代码以使用未格式化的直接访问来进行读写。这为您提供了一个“普通”的原始二进制文件,没有标题。

或者,在您的 python 中,您需要首先读取该 4 字节整数,然后是您的数据。在输出时,您可以根据 paraview 过滤器的预期将整数标头放回或不放。

---------- 这是 python 读取/修改/写入包含单个记录的未格式化顺序 fortran 文件:

import struct
import numpy as np
f=open('infile','rb')
recl=struct.unpack('i',f.read(4))[0]
numval=recl/np.dtype('float32').itemsize
data=np.fromfile(f,dtype='float32',count=numval)
endrec=struct.unpack('i',f.read(4))[0]
if endrec is not recl: print "error unexpected end rec"
f.close()
f=open('outfile') 
f.write(struct.pack('i',recl))
for i in range(0,len(data)):data[i] = data[i]**2  #example data modification
data.tofile(f)
f.write(struct.pack('i',recl)

只需循环多条记录。请注意,此处的数据被读取为向量并假定为所有浮点数。当然,您需要知道实际的数据类型才能使用它。另外请注意,您可能需要根据平台处理字节顺序问题。

于 2013-02-25T16:37:59.773 回答