我想在numpy张量上沿着指定的轴用0进行填充。
例如,我有形状为
(4,3,2)
的张量r
,但我只想填充最后两个轴(即仅填充矩阵)。是否可以使用一行python代码实现?(4,3,2)
的张量r
,但我只想填充最后两个轴(即仅填充矩阵)。是否可以使用一行python代码实现?np.pad()
:a = np.ones((4, 3, 2))
# npad is a tuple of (n_before, n_after) for each dimension
npad = ((0, 0), (1, 2), (2, 1))
b = np.pad(a, pad_width=npad, mode='constant', constant_values=0)
print(b.shape)
# (4, 6, 5)
print(b)
# [[[ 0. 0. 0. 0. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]]
# [[ 0. 0. 0. 0. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]]
# [[ 0. 0. 0. 0. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]]
# [[ 0. 0. 0. 0. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 1. 1. 0.]
# [ 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0.]]]
这个函数会在特定轴的末尾进行填充。
如果你想要两边都填充,只需修改它。
def pad_along_axis(array: np.ndarray, target_length: int, axis: int = 0) -> np.ndarray:
pad_size = target_length - array.shape[axis]
if pad_size <= 0:
return array
npad = [(0, 0)] * array.ndim
npad[axis] = (0, pad_size)
return np.pad(array, pad_width=npad, mode='constant', constant_values=0)
例子:
>>> import numpy as np
>>> a = np.identity(5)
>>> b = pad_along_axis(a, 7, axis=1)
>>> print(a, a.shape)
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]] (5, 5)
>>> print(b, b.shape)
[[1. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0.]] (5, 7)
len(array.shape) == array.ndim
。如果 pad_size <= 0
,你可以安全地 return
。最后,npad = [(0, 0)] * array.ndim
更短 :) - bersdef symmetric_pad_array(input_array: np.ndarray, target_shape: tuple, pad_value: int) -> np.ndarray:
for dim_in, dim_target in zip(input_array.shape, target_shape):
if dim_target < dim_in:
raise Exception("`target_shape` should be greater or equal than `input_array` shape for each axis.")
pad_width = []
for dim_in, dim_target in zip(input_array.shape, target_shape):
if (dim_in-dim_target)%2 == 0:
pad_width.append((int(abs((dim_in-dim_target)/2)), int(abs((dim_in-dim_target)/2))))
else:
pad_width.append((int(abs((dim_in-dim_target)/2)), (int(abs((dim_in-dim_target)/2))+1)))
return np.pad(input_array, pad_width, 'constant', constant_values=pad_value)
>>> a = np.array(np.arange(0,27)).reshape(3,3,3)
>>> target_shape = (3,5,5)
>>> symmetric_pad_array(a, target_shape, pad_value=0)
array([[[ 0, 0, 0, 0, 0],
[ 0, 0, 1, 2, 0],
[ 0, 3, 4, 5, 0],
[ 0, 6, 7, 8, 0],
[ 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0],
[ 0, 9, 10, 11, 0],
[ 0, 12, 13, 14, 0],
[ 0, 15, 16, 17, 0],
[ 0, 0, 0, 0, 0]],
[[ 0, 0, 0, 0, 0],
[ 0, 18, 19, 20, 0],
[ 0, 21, 22, 23, 0],
[ 0, 24, 25, 26, 0],
[ 0, 0, 0, 0, 0]]])