多个文件的平均值?

时间:2015-09-23 12:54:58

标签: arrays fortran average multiple-files

我是Fortran95的新手,我已经完成了以下任务:

  

我的N个文件的研究数据名称为:file0001.asc, file0002.asc, ..., fileN.asc。   这些文件中的每一个都包含I x J个数字(对所有文件都相同),我需要做的是写一个新文件(让它命名为output.asc),每个文件都有I x J个数字它们是N文件的相同元素的平均值(平均值)。   例如元素:

output(1,3) = sum(file0001(1,3),file0002(1,3),...,fileN(1.3)) / N

整个过程需要非常自动化,因此程序应该计算文件夹中文件的数量N以及文件I x J元素的维度,因为我需要这样做它适用于许多不同的数据集。

编辑:

到目前为止,我已经编写了一些(伪)代码,如下所示:

PROGRAM MultiTableMeanValue 
DIMENSION out(?,?)  !need to find this dimension somehow

OPEN(4,file='output.asc',form='formatted')
10 FORMAT('iso',i3.3,'.dat')

!I create the matrix to sum up the values of the output matrix in every loop

DO i=1,?             ! (Where “?” is the number of rows and columns which is need to find somehow
 DO j=1,?            ! since I can’t do it manually cause they are like 1000+).
  S(I,j)=0
 ENDDO
ENDDO

READ*, N  !N is the number of files

DO i=001,N !somehow need its format to be 001,002 cuz N is around 400-900, 
           !so I’ll need ‘10 FORMAT’ above
 OPEN(5,file='file',N,'.asc') !My files are file001,file002,…,fileN and 
                              !I need to open each one of these in every loop.
                              !Write their numbers in “out” matrix
                              !then SUM with each of the other files in every
                              !loop and then divide by N.
 DO j=1,?          ! (Where “?” is again the unknown number of rows and columns
  DO k=1,?            
   READ(5,*) out(j,k)
   S(j,k)=S(j,k)+out(j,k)
  END DO
 END DO 
END DO

DO i=1,?
 DO i=1,?
  S(i,j)=S(i,j)/N
  WRITE(4,*)  S(i,j)
 ENDDO
ENDDO

CLOSE(4)
CLOSE(5)

END PROGRAM MultiTableMeanValue

问题:

如何扩展这个初步想法来完成我的任务?

1 个答案:

答案 0 :(得分:1)

程序中缺少的部分是如何获取每个文件中的行数和列数。例如,可以使用wc命令:

来完成此操作
integer :: ncol, nrow, nfile
call system( "head -n 1 file001.dat | wc -w > count ; wc -l file001.dat >> count ; ls file*.dat | wc -w >> count" )

open( 10, file="count", status="old" )
read( 10, * ) ncol, nrow
read( 10, * ) nfile
close( 10 )

,其中

  • head -n 1 file001.dat | wc -w计算第一行(ncol)中的列数
  • wc -l file001.dat计算文件中的行数(nrow)
  • ls file*.dat | wc -w计算文件数(nfile)

这些数字保存在临时文件中并读入程序。然后将必要的数组分配为

real, allocatable, dimension(:,:) :: inp, out
allocate( inp( nrow, ncol ), out( nrow, ncol ) )

其余部分几乎与OP的计划相同:

character(100) :: str
integer :: ifile

out = 0.0
do ifile = 1, nfile
    write( str, "('file', i3.3, '.dat')" ) ifile    !! set file names like file007.dat
    open( 10, file=trim(str), status="old" )
    do irow = 1, nrow
        read( 10, * ) inp( irow, : )
    enddo
    close( 10 )
    out = out + inp
enddo
out = out / real( nfile )

open( 10, file="output.dat" )
write( str, "('(', i0, 'f15.6)')" ) ncol
do irow = 1, nrow
    write( 10, str ) out( irow, : )
enddo
close( 10 )

为了保持准确性,当输入数据的大小或具有替代符号时,使用双精度可能更好。此外,如果您的编译器足够新,则可以使用execute_command_line代替system