You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran实现numpy.roll函数的最优方式及多余行删除方法咨询

Fortran实现类似numpy.roll的功能问题解答

背景:numpy.roll的功能

Python的numpy.roll函数可沿指定轴滚动数组,示例如下:

from numpy import roll, array
x = array([[1,0,2],[2,1,9],[5,5,1]])
print(roll(x, 1, axis=0))

运行后矩阵x被转换为:

array([[5, 5, 1],
       [1, 0, 2],
       [2, 1, 9]])

Fortran实现尝试

尝试通过切片矩阵行并附加到原矩阵的方式实现该功能,代码如下:

program myfun

implicit none
integer, parameter :: N=3
real, dimension(N,N) :: m
integer :: i, j

m = 0
do i = 1, N
    m(i, i) = 1.0
enddo
m(3,1) = 2
m(3,2) = 9
m(1,3) = 5
m(1,2) = 2
m(2,3) = 5

print *, '', [m(:,N), m]

end program myfun

运行后得到的结果多出一行:

[5, 5, 1]
[1, 0, 2]
[2, 1, 9]
[5, 5, 1]  <- 需要删除此行(如何操作?)

问题解答

1. 这是不是最优实现方式?

这种拼接切片后再删除行的方式并非最优。原因在于Fortran是列主序存储,直接拼接容易出现维度匹配错误,且会生成不必要的临时数组,降低效率。更高效的方式是直接通过切片赋值构造目标数组,无需后续删除操作。

2. 正确的实现方式(避免多余行)

要实现沿轴0(行方向)滚动1次的效果,本质是把矩阵的最后一行移到开头,拼接剩余的前N-1行。由于Fortran数组拼接是按列优先,需要用reshape确保维度正确,代码示例如下:

program myfun
    implicit none
    integer, parameter :: N=3
    real, dimension(N,N) :: m, rolled_m
    integer :: i, j

    m = 0
    do i = 1, N
        m(i, i) = 1.0
    enddo
    m(3,1) = 2
    m(3,2) = 9
    m(1,3) = 5
    m(1,2) = 2
    m(2,3) = 5

    ! 沿轴0滚动1次:将最后一行移到开头,拼接前N-1行
    rolled_m = reshape([m(N,:), m(1:N-1,:)], [N, N])

    ! 逐行打印结果
    do i = 1, N
        print *, rolled_m(i,:)
    enddo
end program myfun

运行此代码会直接得到正确的3×3矩阵,无需处理多余行。如果要支持任意滚动步数,可以通过计算偏移量来调整切片范围,比如滚动k步时,取最后k行拼接前N-k行。

内容的提问来源于stack exchange,提问作者Medulla Oblongata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:22:46