python numpy roll with padding

mar*_*ard 34 python arrays numpy

我想在python中滚动一个2D numpy,除了我想用零填充末尾而不是滚动数据就好像它是周期性的.

具体来说,以下代码

import numpy as np

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

np.roll(x, 1, axis=1)
Run Code Online (Sandbox Code Playgroud)

回报

array([[3, 1, 2],[6, 4, 5]])
Run Code Online (Sandbox Code Playgroud)

但我更喜欢的是

array([[0, 1, 2], [0, 4, 5]])
Run Code Online (Sandbox Code Playgroud)

我可以用一些笨拙的修饰做到这一点,但我希望有一种方法可以使用快速内置命令.

谢谢

Hoo*_*ked 30

版本1.7.0 numpy.pad中有一个新的numpy函数可以在一行中执行此操作.Pad似乎相当强大,可以做的不仅仅是一个简单的"滚动".((0,0),(1,0))在这个答案中使用的元组表示要填充的矩阵的"边".

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

print np.pad(x,((0,0),(1,0)), mode='constant')[:, :-1]
Run Code Online (Sandbox Code Playgroud)

给予

[[0 1 2]
 [0 4 5]]
Run Code Online (Sandbox Code Playgroud)

  • 如果不明显,这里有5个元素:print np.pad(x,((0,0),(5,0)),mode ='constant')[:,:-5] (3认同)
  • 请注意,“np.roll”将允许负值,但如果您尝试向其发送负值,“np.pad”将给出“ValueError:不能包含负值”。所以功能不太一样。 (3认同)
  • @sh37211 对于“负”移位:`np.pad(x,((0,0),(0,1)), mode='constant')[:, 1:])` (2认同)

Jus*_*eel 14

我不认为你会找到一种更简单的内置方法.修饰对我来说似乎很简单:

y = np.roll(x,1,axis=1)
y[:,0] = 0
Run Code Online (Sandbox Code Playgroud)

如果你想让它更直接,那么也许你可以将roll功能复制到一个新功能并将其更改为你想要的.roll()函数位于site-packages\core\numeric.py文件中.

  • 这应该是公认的答案。我认为 np.roll 应该使用关键字参数来本地完成它。np.pad 不接受负值,无论如何它都会改变数组的形状,这对我来说太过分了。 (3认同)

Ken*_*old 5

我只写了以下内容。可以通过避免zeros_like直接计算形状来更好地进行优化zeros

import numpy as np
def roll_zeropad(a, shift, axis=None):
    """
    Roll array elements along a given axis.

    Elements off the end of the array are treated as zeros.

    Parameters
    ----------
    a : array_like
        Input array.
    shift : int
        The number of places by which elements are shifted.
    axis : int, optional
        The axis along which elements are shifted.  By default, the array
        is flattened before shifting, after which the original
        shape is restored.

    Returns
    -------
    res : ndarray
        Output array, with the same shape as `a`.

    See Also
    --------
    roll     : Elements that roll off one end come back on the other.
    rollaxis : Roll the specified axis backwards, until it lies in a
               given position.

    Examples
    --------
    >>> x = np.arange(10)
    >>> roll_zeropad(x, 2)
    array([0, 0, 0, 1, 2, 3, 4, 5, 6, 7])
    >>> roll_zeropad(x, -2)
    array([2, 3, 4, 5, 6, 7, 8, 9, 0, 0])

    >>> x2 = np.reshape(x, (2,5))
    >>> x2
    array([[0, 1, 2, 3, 4],
           [5, 6, 7, 8, 9]])
    >>> roll_zeropad(x2, 1)
    array([[0, 0, 1, 2, 3],
           [4, 5, 6, 7, 8]])
    >>> roll_zeropad(x2, -2)
    array([[2, 3, 4, 5, 6],
           [7, 8, 9, 0, 0]])
    >>> roll_zeropad(x2, 1, axis=0)
    array([[0, 0, 0, 0, 0],
           [0, 1, 2, 3, 4]])
    >>> roll_zeropad(x2, -1, axis=0)
    array([[5, 6, 7, 8, 9],
           [0, 0, 0, 0, 0]])
    >>> roll_zeropad(x2, 1, axis=1)
    array([[0, 0, 1, 2, 3],
           [0, 5, 6, 7, 8]])
    >>> roll_zeropad(x2, -2, axis=1)
    array([[2, 3, 4, 0, 0],
           [7, 8, 9, 0, 0]])

    >>> roll_zeropad(x2, 50)
    array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0]])
    >>> roll_zeropad(x2, -50)
    array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0]])
    >>> roll_zeropad(x2, 0)
    array([[0, 1, 2, 3, 4],
           [5, 6, 7, 8, 9]])

    """
    a = np.asanyarray(a)
    if shift == 0: return a
    if axis is None:
        n = a.size
        reshape = True
    else:
        n = a.shape[axis]
        reshape = False
    if np.abs(shift) > n:
        res = np.zeros_like(a)
    elif shift < 0:
        shift += n
        zeros = np.zeros_like(a.take(np.arange(n-shift), axis))
        res = np.concatenate((a.take(np.arange(n-shift,n), axis), zeros), axis)
    else:
        zeros = np.zeros_like(a.take(np.arange(n-shift,n), axis))
        res = np.concatenate((zeros, a.take(np.arange(n-shift), axis)), axis)
    if reshape:
        return res.reshape(a.shape)
    else:
        return res
Run Code Online (Sandbox Code Playgroud)


Nan*_*ett 5

import numpy as np

def shift_2d_replace(data, dx, dy, constant=False):
    """
    Shifts the array in two dimensions while setting rolled values to constant
    :param data: The 2d numpy array to be shifted
    :param dx: The shift in x
    :param dy: The shift in y
    :param constant: The constant to replace rolled values with
    :return: The shifted array with "constant" where roll occurs
    """
    shifted_data = np.roll(data, dx, axis=1)
    if dx < 0:
        shifted_data[:, dx:] = constant
    elif dx > 0:
        shifted_data[:, 0:dx] = constant

    shifted_data = np.roll(shifted_data, dy, axis=0)
    if dy < 0:
        shifted_data[dy:, :] = constant
    elif dy > 0:
        shifted_data[0:dy, :] = constant
    return shifted_data
Run Code Online (Sandbox Code Playgroud)

此函数适用于 2D 数组,并用您选择的常量替换滚动值。