Python 如何有效地将numpy数组调整为给定形状,并在必要时使用零填充?

Python 如何有效地将numpy数组调整为给定形状,并在必要时使用零填充?,python,numpy,numpy-ndarray,Python,Numpy,Numpy Ndarray,我想基于另一个numpy数组创建一个给定形状的数组。尺寸的数量将匹配,但各轴的尺寸将不同。如果原始尺寸太小,我想用零填充它以满足要求。需要澄清的预期行为示例: embedding = np.array([ [1, 2, 3, 4], [5, 6, 7, 8] ]) resize_with_outer_zeros(embedding, (4, 3)) = np.array([ [1, 2, 3], [5, 6, 7], [0, 0, 0], [0,

我想基于另一个numpy数组创建一个给定形状的数组。尺寸的数量将匹配,但各轴的尺寸将不同。如果原始尺寸太小,我想用零填充它以满足要求。需要澄清的预期行为示例:

embedding = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8]
])

resize_with_outer_zeros(embedding, (4, 3)) = np.array([
    [1, 2, 3],
    [5, 6, 7],
    [0, 0, 0],
    [0, 0, 0]
])
我想我通过下面的功能实现了期望的行为

def resize_with_outer_zeros(embedding: np.ndarray, target_shape: Tuple[int, ...]) -> np.ndarray:
    padding = tuple((0, max(0, target_size - size)) for target_size, size in zip(target_shape, embedding.shape))
    target_slice = tuple(slice(0, target_size) for target_size in target_shape)
    return np.pad(embedding, padding)[target_slice]

然而,我对它的效率和优雅性有强烈的怀疑,因为它涉及许多纯python元组操作。有更好、更简洁的方法吗?

我只需要使用一个零矩阵并运行一个嵌套的for循环来设置旧数组中的值-剩余的位置将自动用零填充

将numpy作为np导入 def resize_arrayarray,新_大小: Z=np.0新尺寸 对于我在兰格伦茨: 对于rangelenZ[i]中的j: 尝试: Z[i][j]=数组[i][j] 除索引器外:以防万一数组[i][j]在新大小中不存在,应该被截断 通过 返回Z 嵌入=np.数组[[1,2,3,4],[5,6,7,8]] printresize_arrayembedding,4,3
我只需要使用一个零矩阵并运行一个嵌套的for循环来设置旧数组中的值——剩余的位置将自动用零填充

将numpy作为np导入 def resize_arrayarray,新_大小: Z=np.0新尺寸 对于我在兰格伦茨: 对于rangelenZ[i]中的j: 尝试: Z[i][j]=数组[i][j] 除索引器外:以防万一数组[i][j]在新大小中不存在,应该被截断 通过 返回Z 嵌入=np.数组[[1,2,3,4],[5,6,7,8]] printresize_arrayembedding,4,3
我不认为你能做得更好,但与其使用pad,然后切片,只需在正确的大小上做零,然后赋值-这将把它切割成一个列表,而不是两个

嵌入=np.array[ [1, 2, 3, 4], [5, 6, 7, 8] ] z=np.零4,3 s=tuple[sliceNone,minza,ea for za,zipz.shape中的ea,embedding.shape] z[s]=嵌入[s] Z 数组[[1,2,3.], [5., 6., 7.], [0., 0., 0.], [0., 0., 0.]]
我不认为你能做得更好,但与其使用pad,然后切片,只需在正确的大小上做零,然后赋值-这将把它切割成一个列表,而不是两个

嵌入=np.array[ [1, 2, 3, 4], [5, 6, 7, 8] ] z=np.零4,3 s=tuple[sliceNone,minza,ea for za,zipz.shape中的ea,embedding.shape] z[s]=嵌入[s] Z 数组[[1,2,3.], [5., 6., 7.], [0., 0., 0.], [0., 0., 0.]]
如果您知道您的阵列不会大于某个大小的r,c,为什么不:

def pad_with_zeros(A, r, c):
   out = np.zeros((r, c))
   r_, c_ = np.shape(A)
   out[0:r_, 0:c_] = A
   return out
如果你想支持任意维张量,它会变得有点难看,但原理是一样的:

def pad(A, shape):
   out = np.zeros(shape)
   out[tuple(slice(0, d) for d in np.shape(A))] = A
   return out
并且要支持比您要填充的阵列更大的阵列,请执行以下操作:

def pad(A, shape):
    shape = np.max([np.shape(A), shape], axis=0)
    out = np.zeros(shape)
    out[tuple(slice(0, d) for d in np.shape(A))] = A
    return out

如果您知道您的阵列不会大于某个大小的r,c,为什么不:

def pad_with_zeros(A, r, c):
   out = np.zeros((r, c))
   r_, c_ = np.shape(A)
   out[0:r_, 0:c_] = A
   return out
如果你想支持任意维张量,它会变得有点难看,但原理是一样的:

def pad(A, shape):
   out = np.zeros(shape)
   out[tuple(slice(0, d) for d in np.shape(A))] = A
   return out
并且要支持比您要填充的阵列更大的阵列,请执行以下操作:

def pad(A, shape):
    shape = np.max([np.shape(A), shape], axis=0)
    out = np.zeros(shape)
    out[tuple(slice(0, d) for d in np.shape(A))] = A
    return out

使用纯python编写的循环似乎比使用np.pad和切片进行初步形状计算更糟糕?使用纯python编写的循环似乎比使用np.pad和切片进行初步形状计算更糟糕?是的,这个IMHO看起来更好一些。我将比较两种变体的速度,稍后报告结果。是的,这个IMHO看起来好一点。我将比较两种变体的速度,稍后报告结果。发布速度比思考速度快一点,请查看编辑。发布速度比思考速度快一点,请查看编辑。