在Fortran中统计文本数据中变量的频率 [英] Counting frequency of variables in text data in Fortran

查看:0
本文介绍了在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中前一ID的最后一行
  4. 写出i0..i1之间的所有行

示例实现

! 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

这篇关于在Fortran中统计文本数据中变量的频率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆