在Python中读取直接访问fortran无格式文件

2024-04-16 23:14:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python还不太熟悉,我从头开始用Python编写可视化代码(以避免使用昂贵的专有程序,如IDL)。到目前为止,我一直使用IDL和gnuplot。我想做的是:

我使用fortran将二维数组写入未格式化的直接访问文件,我希望能够用python读取这些文件。下面给出了准确的测试代码。实际的代码是一个巨大的并行代码,但数据输出几乎是完全相同的格式。

program binary_out
implicit none
integer :: i,j,t,rec_array
double precision, dimension(100,100) :: fn
double precision, parameter :: p=2*3.1415929
INQUIRE(IOLENGTH=rec_array) fn
open(unit=10,file='test',status='new',form='unformatted',access='direct',recl=rec_array)                                                                           
   fn=0
   write(10,rec=1) fn
do t=1,3
do i=1,100
   do j=1,100
      fn(i,j)=sin(i*p*t/100)*cos(j*p*t/100)
   enddo
enddo
   write(10,rec=t+1) fn
enddo
close(10)
end program binary_out

对于t=1,程序应该给我零,对于t值的增加,应该给我增加“孤岛”的数量。但是当我使用下面给出的python代码阅读它时,我得到的只是零。如果删除第一个零的write语句,那么无论在python代码中使用的“time slice”值是什么,都只得到第一个时间片。我目前掌握的代码是:

#!/usr/bin/env python
import scipy
import glob
import numpy as np
import matplotlib.pyplot as plt
import os, sys
from pylab import *

def readslice(inputfilename,field,nx,ny,timeslice):
   f=open(inputfilename,'r')
   f.seek(timeslice*nx*ny)
   field=np.fromfile(inputfilename,dtype='d',count=nx*ny)
   field=np.reshape(field,(nx,ny))
   return field

a=np.dtype('d')
a=readslice('test',a,100,100,2)

im=plt.imshow(a)
plt.show()

我希望def readslice能够在时间间隔等于I的情况下在I处读取记录。为此,我尝试使用f.seek,但它似乎不起作用。numpy.fromfile似乎开始读取第一条记录本身。如何使numpy.from file从文件中的特定点读取?

我仍在努力适应Python风格并深入研究文档。任何帮助和指点都将不胜感激。


Tags: 代码importnumpyfieldnppltarraydo
2条回答

下面是一个适合您的python代码:

def readslice(inputfilename,nx,ny,timeslice):
   f = open(inputfilename,'rb')
   f.seek(8*timeslice*nx*ny)
   field = np.fromfile(f,dtype='float64',count=nx*ny)
   field = np.reshape(field,(nx,ny))
   f.close()
   return field

在原始代码中,将文件名作为第一个参数传递给np.fromfile,而不是文件对象f。因此,np.fromfile创建了一个新的文件对象,而不是使用您想要的对象。这就是为什么它从文件开始就一直在读取。此外,f.seek将字节数作为参数,而不是元素数。我将它硬编码为8以适合您的数据,但如果您愿意,可以将其设为通用。此外,readslice中的字段参数也是多余的。希望这有帮助。

我不认为所有的FORTRAN运行时都是相同的;有些帧记录,有些则不一样,而且我也不太相信那些进行记录成帧的运行时都会以相同的方式进行。当然,它们通常可以读回自己编写的记录,但从一个FORTRAN运行时到另一个运行时的互操作可能不存在。

您可能应该用您选择的FORTRAN编写一个小的测试程序,它会编写一些与生产代码类似的记录,然后使用您最喜欢的二进制文件编辑器(我喜欢bpe)来分离结果,但是有许多结果是可用的。

然后,在您了解真正编写的内容之后,使用Python struct模块或类似的模块将内容拉回来。

bpe:http://sourceforge.net/projects/bpe/

相关问题 更多 >