如何将numpy数组进行翻译/移位?

3

如果已经有人提出了类似的问题,请给出链接并关闭此线程。我不确定要搜索什么关键字。

我正在尝试将numpy数组的非零条目向固定方向移动,例如,假设我有一个2D数组:

0 1 2 0
0 3 0 0
0 0 0 0
0 0 0 0

将其向右下平移一个单位,将会产生以下数组:
0 0 0 0
0 0 1 2
0 0 3 0
0 0 0 0

假设非零条目超出界限,它们会被简单地删除。我该怎么做?
编辑:显然有一些重复的问题?移动numpy数组中的元素我真的不明白为什么它们是相同的问题,因为那个问题涉及到循环超出范围的内容,所以更像是一个“滚动”操作而不是移位。此外,我喜欢这里的解决方案,它非常简单和易读。
再次编辑:修正了一些格式。

1
除了你可能正在寻找的边缘行为外,你可以使用 np.roll 进行保存。 你也可以通过切片构造一个新的数组。 - Andras Deak -- Слава Україні
请将您的值编辑为1、2、3,而不是2、2、2,这样我们就可以看到您想要的移位类型,目前可能有许多不同的选项。 - Ofer Sadan
1
类似于 shift=(1,1); new=np.zeros_like(old); new[shift[0]:,shift[1]:]=old[:-shift[0],:-shift[1]] 这样的代码,可能会有一些 off-by-one 的错误。 - Andras Deak -- Слава Україні
1
可能是Shift elements in a numpy array的重复问题。 - Andras Deak -- Слава Україні
2个回答

6
使用 NumPy 中的 roll 方法。
>>> import numpy as np
>>> m
array([[0, 1, 2, 0],
       [0, 3, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])
>>> m = np.roll(m, 1, axis=0) # shift 1 place in horizontal axis
>>> m = np.roll(m, 1, axis=1) # shift 1 place in vertical axis
>>> m
array([[0, 0, 0, 0],
       [0, 0, 1, 2],
       [0, 0, 3, 0],
       [0, 0, 0, 0]])

https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.roll.html


2

为了简单地管理边缘,您可以将数组扩大到更大的大小:

square=\
array([[0, 2, 2, 0],
       [0, 2, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]], dtype=int64)

n,m=square.shape
bigsquare=np.zeros((3*n,3*m),square.dtype) 
bigsquare[n:2*n,m:2*m]=square

然后 shift 只是一种视图:

def shift(dx,dy):
    x=n-dx
    y=m-dy
    return bigsquare[x:x+n,y:y+m]

print(shift(1,1))

#[[0 0 0 0]
# [0 0 2 2]
# [0 0 2 0]
# [0 0 0 0]]

这是一个不太具有信息性的副本视图。 - Andras Deak -- Слава Україні
@AndrasDeak 啊,我本来就不打算直接在原地编辑,对我来说复制一份就可以了,因为我大部分的东西都还是正常的。 - Evan Pu
@EvanPu 我知道,你实际上没有其他方法可以做到这一点。我刚才想起了B. M.的“移位只是一个视图”的评论。 - Andras Deak -- Слава Україні

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接