python - numpy pad 是如何实现的(对于常量值)

标签 python arrays numpy pad

我正在尝试在常量模式下在 theano 中实现 numpy pad 函数。它是如何在 numpy 中实现的?假设填充值仅为 0。

给定一个数组

a = np.array([[1,2,3,4],[5,6,7,8]])
# pad values are just 0 as indicated by constant_values=0
np.pad(a, pad_width=[(1,2),(3,4)], mode='constant', constant_values=0)

会回来

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

现在,如果我事先知道 a 的维数,我可以通过创建一个新的数组来实现这一点,新的维度填充填充值并填充该数组中的相应元素。但是,如果我不知道输入数组的维度怎么办?虽然我仍然可以从输入数组中推断出输出数组的维数,但我无法在不知道其中维数的情况下对其进行索引。还是我遗漏了什么?

也就是说,如果我知道输入维度是 3,那么我可以:

zeros_array[pad_width[0][0]:-pad_width[0][1], pad_width[1][0]:-pad_width[1][1], pad_width[2][0]:-pad_width[2][1]] = a

其中 zeros 数组是使用输出维度创建的新数组。

但如果我事先不知道 ndim,我将无法执行此操作。

最佳答案

我的直觉是:

def ...(arg, pad):
    out_shape = <arg.shape + padding>  # math on tuples/lists
    idx = [slice(x1, x2) for ...]   # again math on shape and padding
    res = np.zeros(out_shape, dtype=arg.dtype)
    res[idx] = arg     # may need tuple(idx)
    return res

换句话说,创建目标数组,并使用适当的索引元组复制输入。构建所需的形状和切片需要一些数学运算,可能还需要迭代,但如果乏味的话,这应该是直截了当的。

然而,np.pad 似乎在轴上迭代(如果我确定了正确的替代方案:

   newmat = narray.copy()
   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)

其中 _prepend_const 是:

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

(和 append 类似)。所以它为每个维度分别添加每个前片和后片。从概念上讲,这很简单,即使它可能不是最快的。

In [601]: np.lib.arraypad._prepend_const(np.ones((3,5)),3,0,0)
Out[601]: 
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

In [604]: arg=np.ones((3,5),int)
In [605]: for i in range(2):
     ...:     arg=np.lib.arraypad._prepend_const(arg,1,0,i)
     ...:     arg=np.lib.arraypad._append_const(arg,2,2,i)
     ...:     
In [606]: arg
Out[606]: 
array([[0, 0, 0, 0, 0, 0, 2, 2],
       [0, 1, 1, 1, 1, 1, 2, 2],
       [0, 1, 1, 1, 1, 1, 2, 2],
       [0, 1, 1, 1, 1, 1, 2, 2],
       [0, 2, 2, 2, 2, 2, 2, 2],
       [0, 2, 2, 2, 2, 2, 2, 2]])

关于python - numpy pad 是如何实现的(对于常量值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40076280/

相关文章:

python - Pandas 数据框的递归转置

python - Django 无效 block 标记 : 'static'

python - 获取一小时过去的微秒

python - 如何检查列表项是否存在于另一个列表中

c - 在 C 中声明数组大小

python - 如何在Python中编写numpy矩阵的函数

python - 一起使用模拟 (MyHDL) 和 wxPython

javascript - 使用数组表示法了解何时将属性设置为对象

arrays - typescript :具有属性/数组作为类的数组

python - Scipy randint 与 numpy randint