计算 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
您可以通过以下方式解决您的问题:
- 用户 ID 从第
i0
行开始
- 迭代行直到找到新的用户 ID(保存
i1
中上一个 ID 的最后一行
- 写出
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
我有一个包含以下信息的数据文件:
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
您可以通过以下方式解决您的问题:
- 用户 ID 从第
i0
行开始
- 迭代行直到找到新的用户 ID(保存
i1
中上一个 ID 的最后一行
- 写出
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