Python Fortran的无格式输入/输出

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

我正在尝试使用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.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中的直接访问文件实际上与通用的非格式化文件相同