Python Fortran的无格式输入/输出
我正在尝试使用FortranFile获得一个输出,可以在F95编写的模拟代码中使用。我很难让fortranfile正常工作。也许是因为我不明白它是怎么工作的。我的问题是: 如果我想使用FortranFile编写1D数组,它可以正常工作:Python Fortran的无格式输入/输出,python,fortran,Python,Fortran,我正在尝试使用FortranFile获得一个输出,可以在F95编写的模拟代码中使用。我很难让fortranfile正常工作。也许是因为我不明白它是怎么工作的。我的问题是: 如果我想使用FortranFile编写1D数组,它可以正常工作: nx = 128 bxo = np.zeros(nx, dtype=float) bxo = something import fortranfile as fofi bxf=fofi.FortranFile('Fbx.dat',mode='w') bxf.wr
nx = 128
bxo = np.zeros(nx, dtype=float)
bxo = something
import fortranfile as fofi
bxf=fofi.FortranFile('Fbx.dat',mode='w')
bxf.writeReals(bxo,prec='d')
bxf.close()
上面的1D版本工作起来很有魅力。当我尝试对2D数组执行此操作时,就会遇到问题
nx = 128; ny = 128
bxo = np.zeros((nx,ny), dtype=float)
bxo = something
import fortranfile as fofi
bxf=fofi.FortranFile('Fbx.dat',mode='w')
bxf.writeReals(bxo,prec='d')
bxf.close()
当我尝试执行此操作时,会出现以下错误:
---------------------------------------------------------------------------
error Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/IPython/utils/py3compat.py in execfile(fname, *where)
173 else:
174 filename = fname
--> 175 __builtin__.execfile(filename, *where)
/Users/parashar/Dropbox/sandbox/test2d.py in <module>()
130 vyf=fofi.FortranFile('Fvy.dat',mode='w')
131 vzf=fofi.FortranFile('Fvz.dat',mode='w')
--> 132 bxf.writeReals(bxo,prec='d')
133 byf.writeReals(byo,prec='d')
134 bzf.writeReals(bzo,prec='d')
/Users/parashar/Dropbox/sandbox/fortranfile.py in writeReals(self, reals, prec)
215 _fmt = self.ENDIAN + prec
216 for r in reals:
--> 217 self.write(struct.pack(_fmt,r))
218 self._write_check(length_bytes)
219
error: required argument is not a float
---------------------------------------------------------------------------
错误回溯(最近一次呼叫上次)
/execfile(fname,*其中)中的Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/IPython/utils/py3compat.py
173.其他:
174 filename=fname
-->175 _uu内置_uuu.execfile(文件名,*其中)
/()中的Users/parashar/Dropbox/sandbox/test2d.py
130 vyf=fofi.FortranFile('Fvy.dat',mode='w')
131 vzf=fofi.FortranFile('Fvz.dat',mode='w')
-->132 bxf.写入项(bxo,prec='d')
133 byf.writerals(byo,prec='d')
134 bzf.书面材料(bzo,prec='d')
/Users/parashar/Dropbox/sandbox/fortranfile.py(self、reals、prec)
215 _fmt=self.ENDIAN+prec
216对于实数形式的r:
-->217自写(结构包(_fmt,r))
218自写检查(长度字节)
219
错误:必需的参数不是浮点
你知道会发生什么吗
谢谢 我从未同时使用过Fortran和Python,对fortranfile.py一无所知,但我最好的猜测是fortranfile不支持numpy 当您使用1D numpy数组或Python数组、列表等时,堆栈跟踪的最后一部分中的迭代表明它需要一个iterable的数字(“对于reals中的r”),而当您尝试序列化2D numpy数组时,我不确定它得到了什么(即“r”最终是什么),可能是iterable的迭代器,或一维数组的可数。简言之,“r”不仅仅是预期的数字(“必需参数不是浮点”),而是其他数字(如1D数组、列表等) 我会试着看看fortranfile中是否有替代writeReals()的方法,如果没有的话,我会在其中找到一种可以处理2D数组的方法
首先,我会在“self.write()”行(217)之前添加一个诊断打印,它告诉您“r”实际上是什么,因为它不是预期的浮点。我从来没有同时使用Fortran和Python做过任何事情,而且对fortranfile.py完全不了解,但我最好的猜测是fortranfile不知道numpy 当您使用1D numpy数组或Python数组、列表等时,堆栈跟踪的最后一部分中的迭代表明它需要一个iterable的数字(“对于reals中的r”),而当您尝试序列化2D numpy数组时,我不确定它得到了什么(即“r”最终是什么),可能是iterable的迭代器,或一维数组的可数。简言之,“r”不仅仅是预期的数字(“必需参数不是浮点”),而是其他数字(如1D数组、列表等) 我会试着看看fortranfile中是否有替代writeReals()的方法,如果没有的话,我会在其中找到一种可以处理2D数组的方法
首先,我会在“self.write()”行(217)之前添加一个诊断打印,告诉您“r”实际上是什么,因为它不是预期的浮点值。我喜欢Emmet的建议,但鉴于我对python的了解非常基础,要实现一个简短的目标需要付出很多努力。我刚刚意识到我可以用一种稍微不同的方式处理这种情况 Fortran中的直接访问文件不像通常的未格式化Fortran文件那样具有不必要的前导/尾随信息。因此,处理Fortran和Python之间交换的未格式化数据的最简单方法是将文件视为Fortran中的直接访问。下面是一个示例,说明如何使用python/fortran中的数据 Python代码:
import numpy as np
nx=128; ny=128;
bxo=np.zeros((nx,ny),dtype=float)
bxo=something
bxf=open('Fbx.dat',mode='wb')
np.transpose(bxo).tofile(bxf) # We transpose the array to map indices
# from python to fortran properly
bxo.close()
Fortran代码:
program test
implicit none
double precision, dimension(128,128) :: bx
integer :: NNN, i, j
inquire(iolength=NNN) bx
open(unit=23,file='Fbx.dat',form='unformatted',status='old',&
access='direct',recl=NNN)
read(23,rec=1) bx
close(23)
! Write it out to a text file to test it
! by plotting in gnuplot
do i=1,128; do j=1,128
write(23,*) i,j,bx(i,j)
enddo; enddo
end
因为我们使用标准的二进制格式来读/写数据,所以与FortranFile方法不同,这种方法可以处理任何大小的数组
我意识到,通过坚持使用Fortran中的直接访问文件,我们可以与其他语言(如Python、IDL等)有更广泛的兼容性。这样,我们就不必担心奇怪的前导尾随标记、endian等
我希望这也能对我这种情况下的其他人有所帮助。我喜欢埃米特的建议,但鉴于我对python的了解非常基础,要实现一个短期目标需要付出很多努力。我刚刚意识到我可以用一种稍微不同的方式处理这种情况 Fortran中的直接访问文件不像通常的未格式化Fortran文件那样具有不必要的前导/尾随信息。因此,处理Fortran和Python之间交换的未格式化数据的最简单方法是将文件视为Fortran中的直接访问。下面是一个示例,说明如何使用python/fortran中的数据 Python代码:
import numpy as np
nx=128; ny=128;
bxo=np.zeros((nx,ny),dtype=float)
bxo=something
bxf=open('Fbx.dat',mode='wb')
np.transpose(bxo).tofile(bxf) # We transpose the array to map indices
# from python to fortran properly
bxo.close()
Fortran代码:
program test
implicit none
double precision, dimension(128,128) :: bx
integer :: NNN, i, j
inquire(iolength=NNN) bx
open(unit=23,file='Fbx.dat',form='unformatted',status='old',&
access='direct',recl=NNN)
read(23,rec=1) bx
close(23)
! Write it out to a text file to test it
! by plotting in gnuplot
do i=1,128; do j=1,128
write(23,*) i,j,bx(i,j)
enddo; enddo
end
因为我们使用标准的二进制格式来读/写数据,所以与FortranFile方法不同,这种方法可以处理任何大小的数组
我意识到,通过坚持使用Fortran中的直接访问文件,我们可以与其他语言(如Python、IDL等)有更广泛的兼容性。这样,我们就不必担心奇怪的前导尾随标记、endian等
我希望这也能对我这种情况下的其他人有所帮助。谢谢你的回答,埃米特!考虑到我对python有相当基本的了解,这将是我的大量时间投入。我刚刚意识到,我可以不用使用FortranFile软件包来做一些事情。fortran中的直接访问文件实际上与通用的非格式化文件相同