在Python2.7中读取文件,忽略行并分配内存(重写fortran代码)

2024-09-21 01:16:47 发布

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

我对编程非常陌生,正在将fortran90代码转换为Python2.7。到目前为止,我做得还不错,但遇到了一个困难。我需要用Python编写这个子例程,但是我不理解fortran表示法,也找不到任何关于Read(1,*)行的Python等价物的信息。在

任何帮助都将不胜感激。在

SUBROUTINE ReadBCoutput(filenameBC,count,timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray)

! read Bruzual & Charlot (2003) stellar population synthesis models into arrays

CHARACTER*500,INTENT(IN):: filenameBC
INTEGER,INTENT(OUT):: count
REAL,DIMENSION(:),ALLOCATABLE,INTENT(OUT):: timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray

REAL:: logTime,Mbol,g,uMg,gMr,gMi,gMz
REAL,DIMENSION(:),ALLOCATABLE:: timeArrayLocal,MbolArrayLocal,uArrayLocal,gArrayLocal,rArrayLocal,iArrayLocal,zArrayLocal

! open file and read off unnecessary 29 lines of comments
OPEN(1,FILE=TRIM(filenameBC),RECL=2000)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)
READ(1,*)

! now read arrays
count=0
ALLOCATE(timeArray(count))
ALLOCATE(MbolArray(count))
ALLOCATE(uArray(count))
ALLOCATE(gArray(count))
ALLOCATE(rArray(count))
ALLOCATE(iArray(count))
ALLOCATE(zArray(count))
IOEnd=0
DO WHILE(IOEnd>-1)
 READ(1,*,IOSTAT=IOEnd) logTime,Mbol,g,uMg,gMr,gMi,gMz
!print*,'filename is',filenameBC
   IF (IOEnd>-1) THEN ! not at end of file yet
     ! add new element to list
    count=count+1
    ALLOCATE(timeArrayLocal(count-1))
    ALLOCATE(MbolArrayLocal(count-1))
    ALLOCATE(uArrayLocal(count-1))
    ALLOCATE(gArrayLocal(count-1))
    ALLOCATE(rArrayLocal(count-1))
    ALLOCATE(iArrayLocal(count-1))
    ALLOCATE(zArrayLocal(count-1))
    DO countInside=1,count-1
       timeArrayLocal(countInside)=timeArray(countInside)
       MbolArrayLocal(countInside)=MbolArray(countInside)
       uArrayLocal(countInside)=uArray(countInside)
       gArrayLocal(countInside)=gArray(countInside)
       rArrayLocal(countInside)=rArray(countInside)
       iArrayLocal(countInside)=iArray(countInside)
       zArrayLocal(countInside)=zArray(countInside)
    END DO
    DEALLOCATE(timeArray)
    DEALLOCATE(MbolArray)
    DEALLOCATE(uArray)
    DEALLOCATE(gArray)
    DEALLOCATE(rArray)
    DEALLOCATE(iArray)
    DEALLOCATE(zArray)
    ALLOCATE(timeArray(count))
    ALLOCATE(MbolArray(count))
    ALLOCATE(uArray(count))
    ALLOCATE(gArray(count))
    ALLOCATE(rArray(count))
    ALLOCATE(iArray(count))
    ALLOCATE(zArray(count))
    DO countInside=1,count-1
       timeArray(countInside)=timeArrayLocal(countInside)
       MbolArray(countInside)=MbolArrayLocal(countInside)
       uArray(countInside)=uArrayLocal(countInside)
       gArray(countInside)=gArrayLocal(countInside)
       rArray(countInside)=rArrayLocal(countInside)
       iArray(countInside)=iArrayLocal(countInside)
       zArray(countInside)=zArrayLocal(countInside)
    END DO
    timeArray(count)=10**logTime
    MbolArray(count)=Mbol
    gArray(count)=g
    uArray(count)=uMg+g
    rArray(count)=g-gMr
    iArray(count)=g-gMi
    zArray(count)=g-gMz
    DEALLOCATE(uArrayLocal)
    DEALLOCATE(gArrayLocal)
    DEALLOCATE(rArrayLocal)
    DEALLOCATE(iArrayLocal)
    DEALLOCATE(zArrayLocal)
    DEALLOCATE(MbolArrayLocal)
    DEALLOCATE(timeArrayLocal)
 END IF
END DO
CLOSE(1)

END SUBROUTINE ReadBCoutput

我不希望有人替我转换整个过程-我只想弄清楚这实际上在做什么,以及在Python中什么是/不需要做的。我可以自己搜索,但我有点被这里要找的东西迷住了。在

非常感谢!在


Tags: readcountdouarrayallocatetimearraygarrayzarray
2条回答

在fortran中,open(1,FILE=TRIM(filenameBC),RECL=2000)打开名为filenameBC的文件。TRIM部分是不必要的,因为fortran运行库将为您完成这项工作(它的python等价物是filenameBC.rstrip())。这里的RECL=2000部分也有点可疑。我不认为它在这里有任何作用,我认为使用它是未定义的行为,因为您的文件应该被连接以进行"sequential"访问。根据第12.10.1节

RECL = rl

rl is an integer expression whose value must be positive. It specifies the length of each record in a file being connected for direct access. If the file is being connected for formatted input/output, the length is the number of characters. If the file is being connected for unformatted input/output, the length is measured in processor-dependent units. For an existing file, the value of rl must be included in the set of allowed record lengths for the file ( 12.2.2). For a new file, the processor creates the file with a set of allowed record lengths that includes the specified value. This specifier must be given when a file is being connected for direct access; otherwise, it must be omitted.

如果是这样的话,我认为它规定了最大线长度。在

Fortran的句柄就是文件的整数。所以,在python中,你会说:

filehandle = open('file')
line = filehandle.readline()  #or better, `next(filehandle)` :)

在fortran中,这与:

^{pr2}$

*基本上可以让您从文件中读取一行。在


请注意,这个fortran代码有一点缺陷,效率非常低。例如,检查IF (IOEnd>-1) THEN在任何不是文件结尾的情况下都会成功(例如,奇怪的错误将被屏蔽,类似于python中的一个空的except)。在python中,您只需将这些信息打包到一个列表中并动态地增长列表python将处理您需要执行的所有重新分配。最后,您可以选择将列表转换为numpyndarray。在

在伪python代码中,这大致相当于:

data_list = []
with open(filenameBC.rstrip()) as fin:
    for _ in range(29): #throw away first 29 lines (I think I counted right ...)
        next(fin)

    for line in fin:
        data_list.append([float(x) for x in line.strip()])

timeArray,MbolArray,uArray,gArray,rArray,iArray,zArray = zip(*data_list)

READ(1,*)正在读取。。。。从你的文件中取出一些东西,而不是把它保存起来,也就是说,把它扔掉。所有这些READ(1,*)语句只是在文件中滚动的一种方式,直到您获得实际需要的数据。(顺便说一句,这不是最简洁的编码方式。写这段FORTRAN代码的人可能在很多方面都很聪明,但不是一个非常好的程序员。或者他们可能很匆忙。)一个python等价物就是

>>> infile.readline()

你可以把所有的数据都转换成数值。在

但是,如果您想看一下NumPy,它有两个可以将数据读作数字的例程:loadtxt和{}。也许还有一些其他的,但这些是我发现最有帮助的。在

相关问题 更多 >

    热门问题