计算 Fortran 文本数据中变量的频率

Counting frequency of variables in text data in Fortran

我有一个包含以下信息的数据文件:

 x         y       k               !name for the columns to explain

200316157 123 2004121 
200316157 456 2004121 
200316157 789 2004121 
200519776 456 2007234 
200519776 789 2007234 
200812334 123 2010333 
200812334 789 2010333 
200812334 345 2010333 
200812334 567 2010333 

所以每一行都包含一个特定的唯一信息,但该行的其余部分是重复的信息。文件将被排序,因此每个人的信息将始终集中在一个地方。

我想计算每个独特的人(由第一列定义)出现在数据中的频率并将该信息添加到数据中,因此它看起来像这样:

     x     y      k        !name for the columns to explain

200316157 123 2004121 3
200316157 456 2004121 3
200316157 789 2004121 3
200519776 456 2007234 2
200519776 789 2007234 2
200812334 123 2010333 4
200812334 789 2010333 4
200812334 345 2010333 4
200812334 567 2010333 4

这可能吗?如果您有任何提示和技巧,我很乐意听到!

这是我迄今为止的微弱尝试:

program counting
implicit none 

integer, parameter :: n=40000    !lenght of file

integer, dimension(1:n) :: x, y, k, icount

integer :: i

open (unit=20, file="data.txt", status="old")



do i = 1, n
read (20,2001) x(i), y(i), k(i),
2001 format (i9, 1x, i3, 1x, i7,)
enddo

open (unit=21, file="data2.txt", status="new")   !a new datafile

icount(i) = 0

do
if (x(i) == x(i)) then                      !how can I compare a line to the previous one?????
icount = icount +i
write (21,2021) x(i), y(i), k(i), icount(i)
endif
icount(i) = 0
enddo


2021 format (i9, 1x, i3, 1x, i7, 1x, i1)  !a new datafile

endprogram counting

但这唯一做的是:

200316157 123 2004121 1
200316157 456 2004121 2
200316157 789 2004121 3
200519776 456 2007234 4
200519776 789 2007234 5
200812334 123 2010333 6
200812334 789 2010333 7
200812334 345 2010333 8
200812334 567 2010333 9

我不知道如何比较第 2 行和第 1 行,然后计算每个独特人物的出现次数?

*编辑

我也在想我能不能得到这样的结果:

200316157 123 2004121 1
200316157 456 2004121 2
200316157 789 2004121 3
200519776 456 2007234 1
200519776 789 2007234 2
200812334 123 2010333 1
200812334 789 2010333 2
200812334 345 2010333 3
200812334 567 2010333 4

您可以通过以下方式解决您的问题:

  1. 用户 ID 从第 i0
  2. 行开始
  3. 迭代行直到找到新的用户 ID(保存 i1
  4. 中上一个 ID 的最后一行
  5. 写出 i0..i1
  6. 之间的所有行

示例实现

! a.f90
program counting
  implicit none

  integer, parameter    :: n = 9 ! length of file
  integer               :: i, iounit, i0, i1
  integer, dimension(n) :: x, y, k

  ! read input file
  open (newunit=iounit, file='data.txt', action='read')
  read (iounit, *)
  read (iounit, *)
  do i = 1, n
    read (iounit, *) x(i), y(i), k(i)
  end do
  close (iounit)

  ! compare x array and write out data
  open (newunit=iounit, file='data2.txt', action='write')
  i1 = 0
  do
    ! set i0, i1
    !   i0: line where specific user id starts
    !   i1: line where specific user id ends
    i0 = i1 + 1
    do i = i0, n
      if (x(i) /= x(i0)) exit
      i1 = i
    end do

    do i = i0, i1
      write (iounit, '(i0, 1x, i0, 1x, i0, 1x, i0)') x(i), y(i), k(i), i1-i0+1   ! last column will be total number
      ! write (iounit, '(i0, 1x, i0, 1x, i0, 1x, i0)') x(i), y(i), k(i), i-i0+1 ! last column will increase by 1, resets for new user id
    end do

    if (i1 == n) exit
  end do
  close (iounit)
end program

关于如何写出最后一列,有两个选项。 只需取消注释那一行。

对于给定的输入文件

$ cat data.txt
 x         y       k               !name for the columns to explain

200316157 123 2004121
200316157 456 2004121
200316157 789 2004121
200519776 456 2007234
200519776 789 2007234
200812334 123 2010333
200812334 789 2010333
200812334 345 2010333
200812334 567 2010333

您将收到以下输出

$ gfortran -g -Wall -fcheck=all a.f90 && ./a.out && cat data2.txt
200316157 123 2004121 3
200316157 456 2004121 3
200316157 789 2004121 3
200519776 456 2007234 2
200519776 789 2007234 2
200812334 123 2010333 4
200812334 789 2010333 4
200812334 345 2010333 4
200812334 567 2010333 4