我正在尝试在theano中为恒定模式实现numpy pad功能。如何在numpy中实现?假设pad值只为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]])
现在,如果我事先知道了维度的数量,我可以通过创建填充了pad值的新维度的新数组来实现这一点,并填充此数组中的相应元素。但是,如果我不知道输入数组的尺寸怎么办?虽然我仍然可以从输入数组推断输出数组的维度,但我无法在不知道其中的维数的情况下对其进行索引。或者我错过了什么?
也就是说,如果我知道输入维度是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,我就不能这样做。
答案 0 :(得分:1)
我的直觉是:
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]])