我有一些由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")
这些信息是否足够?
答案 0 :(得分:2)
您是否尝试过使用受控数据数组的.tofile方法?它将以C顺序写入数组,但能够编写纯二进制文件。
.tofile的文档也暗示这与:
相同with open(outfile, 'wb') as fout:
fout.write(manipulated_data.tostring())
答案 1 :(得分: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)
只循环多个记录..请注意,此处的数据被读取为向量并假定为所有浮点数。当然,如果它需要知道要使用的实际数据类型.. 另请注意,您可能需要根据平台处理字节顺序问题。