如何用Fortran实现类似Matlab的矩阵同值行分组提取操作?
Fortran分组提取矩阵行的问题解决
编译错误原因
你遇到的Array index at (1) must be of INTEGER type, found LOGICAL错误,是因为代码里的height((a1(i)== x(i)),:)用了单个逻辑值做数组索引——Fortran要求数组索引必须是整数类型,而a1(i)==x(i)只会返回单个true/false,完全不符合索引要求。
另外原代码还有几个逻辑问题:比如固定分配T1(k,8),但每个分组的行数大概率不等于k;直接用实数类型的maxval(height(:,8))作为循环上限也容易出问题。
修正后的完整代码
下面是实现分组提取功能的正确代码,包含注释说明:
program group_extract implicit none ! 定义矩阵规模,根据你的需求设置为60000行8列 integer, parameter :: TOTAL_ROWS = 60000, COLS = 8 real, dimension(TOTAL_ROWS, COLS) :: height integer, dimension(TOTAL_ROWS) :: col8_int ! 第8列转整数后的数组 integer :: max_group, i, group_row_count integer, dimension(:), allocatable :: target_rows ! 存储符合条件的行索引 real, dimension(:,:), allocatable :: sub_matrix ! 存储分组后的子矩阵 integer, dimension(:), allocatable :: group_values ! 读取数据文件(请替换成你的实际文件名) open(unit=7, file="matrix_data.txt", status="old") read(7, *) height close(7) ! 处理第8列:转整数,获取最大分组值 col8_int = int(height(:, COLS)) max_group = maxval(col8_int) ! 生成分组值数组(1到max_group) allocate(group_values(max_group)) do i = 1, max_group group_values(i) = i end do ! 循环提取每个分组 do i = 1, max_group ! 获取当前分组对应的所有行索引 target_rows = pack([(j, j=1,TOTAL_ROWS)], mask=(col8_int == group_values(i))) group_row_count = size(target_rows) ! 动态分配子矩阵内存(匹配当前分组的行数) if (allocated(sub_matrix)) deallocate(sub_matrix) allocate(sub_matrix(group_row_count, COLS)) ! 提取子矩阵 sub_matrix = height(target_rows, :) ! 这里添加对sub_matrix的操作,比如写入文件、计算等 print *, "分组", group_values(i), "包含", group_row_count, "行" ! 示例:将子矩阵写入单独文件 open(unit=10+i, file="group_"//trim(int_to_str(i))//".txt", status="replace") write(10+i, *) sub_matrix close(10+i) end do ! 释放内存 if (allocated(group_values)) deallocate(group_values) if (allocated(target_rows)) deallocate(target_rows) if (allocated(sub_matrix)) deallocate(sub_matrix) contains ! 辅助函数:整数转字符串,用于生成文件名 function int_to_str(n) result(str_out) integer, intent(in) :: n character(len=20) :: str_out write(str_out, '(I0)') n str_out = adjustl(str_out) end function int_to_str end program group_extract
关键修正点
- 正确获取行索引:用
pack函数生成符合条件的行号数组——[(j, j=1,TOTAL_ROWS)]生成1到总行数的整数序列,mask=(col8_int == group_values(i))筛选出第8列等于当前分组值的行,最终得到整数类型的行索引数组。 - 动态分配子矩阵:每个分组的行数可能不同,所以每次循环都根据当前分组的行数重新分配
sub_matrix,避免内存浪费或溢出。 - 规范类型处理:将第8列转成整数数组后再取最大值,避免实数类型带来的循环上限问题。
内容的提问来源于stack exchange,提问作者Indrajit Nandi
相关产品推荐
相关产品推荐

