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

numpy.roll实现二维ndarray按行不同偏移水平滚动的问题

对np.roll参数规则的正确理解

np.roll是作用于全数组的全局数组操作,官方文档中「偏移元组与axis元组长度必须一致」的规则,核心是给不同的坐标轴分别设置独立的全局偏移,不是给同一个坐标轴上的不同子元素(比如二维数组的不同行)设置差异化偏移。
举个简单例子:传入shift=(1,2), axis=(0,1)时,执行逻辑是先把整个数组沿0轴(行方向)全局滚1位,再沿1轴(列方向)全局滚2位,两次操作都是覆盖全数组的。
你之前写的np.roll(a, [1,2,1,3], axis=(1,1,1,1)),相当于重复4次指定1轴,numpy会按顺序对全数组执行4次列方向全局滚动,最终等价于沿1轴全局滚动(1+2+1+3) % 数组列数位,当然出不了逐行不同偏移的效果。

逐行设置不同水平偏移的实现方案

np.roll原生不支持单轴下不同位置设置不同偏移,这类需求可以用numpy高级索引构造移位索引实现:水平循环滚动的本质就是把每一行的列索引按指定偏移循环移位,再按新索引取数就行。
以你给出的测试数组、偏移量[1,2,1,3]为例,代码如下:

import numpy as np
a = np.array([  
             [6, 3, 9, 2, 3],
             [1, 7, 8, 1, 2],
             [5, 4, 2, 2, 4],
             [3, 9, 7, 6, 5],
            ])
shifts = [1, 2, 1, 3]
n_rows, n_cols = a.shape
# 生成每行的基础列索引矩阵
col_idx = np.tile(np.arange(n_cols), (n_rows, 1))
# 按每行偏移调整列索引,取模实现循环移位,避免负数索引
shifted_col_idx = (col_idx - np.array(shifts).reshape(-1, 1)) % n_cols
# 配合行索引用高级索引取数
row_idx = np.arange(n_rows).reshape(-1, 1)
result = a[row_idx, shifted_col_idx]

运行得到的结果完全符合预期:

array([[3, 6, 3, 9, 2],
       [1, 2, 1, 7, 8],
       [4, 5, 4, 2, 2],
       [7, 6, 5, 3, 9]])

如果要实现按列设置不同垂直偏移,逻辑完全一致,只需要把索引构造逻辑对应到行维度即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:48:15