python numpy roll在任意方向填充

时间:2017-12-11 23:23:54

标签: python arrays numpy

我正在尝试重新定位一组类似图像的数据,我知道x和y维度中的适当偏移。与this问题类似,我想做一些类似“滚动”的事情,但我没有假设周期性边界条件,而是想用零填充数组中的“空”位置。

我的问题比我链接的问题更为通用,因为我想在任意方向上移动数组。在公认的解决方案中,必须始终知道图像被滚动的方向,以便切断适当的边缘。特别是,这是一个公认的解决方案,它涉及将数组x移动1.

import numpy as np
x = np.array([[1, 2, 3],[4, 5, 6]])

print np.pad(x,((0,0),(1,0)), mode='constant')[:, :-1]

但是,要进行相反的操作,必须对以下更改进行硬编码:

import numpy as np
x = np.array([[1, 2, 3],[4, 5, 6]])

print np.pad(x,((0,0),(0,1)), mode='constant')[:, 1:] 
// changed argument of pad
// and array indices

是否有一种简单的方法可以同时实现这两种方法?

1 个答案:

答案 0 :(得分:1)

pad mode的核心是:

newmat = narray.copy()

# API preserved, but completely new algorithm which pads by building the
# entire block to pad before/after `arr` with in one step, for each axis.
if mode == 'constant':
    for axis, ((pad_before, pad_after), (before_val, after_val)) \
            in enumerate(zip(pad_width, kwargs['constant_values'])):
        newmat = _prepend_const(newmat, pad_before, before_val, axis)
        newmat = _append_const(newmat, pad_after, after_val, axis)

因此,pad_width元组(元组)确定了动作,可以在前置或附加常量键盘。请注意,它会在轴上进行迭代。

你自己的代码可能会同样快,因为pad在这里做任何神奇的(或编译的)都没有。

prepend函数执行如下连接:

np.concatenate((np.zeros(padshape, dtype=arr.dtype), arr),
                          axis=axis)

有关详细信息,请参阅np.lib.arraypad.py

因此,对于每个非零填充量,它会在所需形状的零块上连接。

In [280]: x = np.array([[1, 2, 3],[4, 5, 6]])

您的两个pad版本:

In [281]: np.pad(x,((0,0),(1,0)), mode='constant')[:, :-1]
Out[281]: 
array([[0, 1, 2],
       [0, 4, 5]])
In [282]:  np.pad(x,((0,0),(0,1)), mode='constant')[:, 1:]
Out[282]: 
array([[2, 3, 0],
       [5, 6, 0]])

直接insert等价物:

In [283]: res = np.zeros_like(x)
In [284]: res[:,1:] = x[:,:-1]
In [285]: res
Out[285]: 
array([[0, 1, 2],
       [0, 4, 5]])
In [286]: res = np.zeros_like(x)
In [287]: res[:,:-1] = x[:,1:]
In [288]: res
Out[288]: 
array([[2, 3, 0],
       [5, 6, 0]])

您可以在第一个轴上执行相同的操作。一般表达是

res = np.zeros_like(x)
idx1 = (slice(...), slice(...))
idx2 = (slice(...), slice(...))
res[idx1] = x[idx2]

idx元组取决于滚动轴和方向。

e.g。

idx1 = (slice(None), slice(1,None))
idx2 = (slice(None), slice(None,-1))

有2个轴和2个方向,即4对。