如何有效地调整一个numpy数组的大小到一个给定的形状,必要时用零填充?

问题描述 投票:0回答:1

我想在另一个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元组操作。有没有更好、更简洁的方法?

python numpy numpy-ndarray
1个回答
1
投票

我不认为你能做得更好,但不使用 pad 然后再切片,只要做 zeros 大小合适,然后再进行赋值--这就把列表理解减少到了一个,而不是两个。

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

z = np.zeros((4,3))
s = tuple([slice(None, min(za,ea)) for za,ea in zip(z.shape, embedding.shape)])

z[s] = embedding[s]
z
# array([[1., 2., 3.],
#        [5., 6., 7.],
#        [0., 0., 0.],
#        [0., 0., 0.]])

1
投票

如果你知道你的数组不会大于某个尺寸 (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

如果你想支持任意维度的数组(tensors),那就会变得丑陋一些,但原理是一样的。

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

0
投票

我只需要使用一个零矩阵,然后运行一个嵌套的for循环来设置旧数组的值 -- 剩下的地方会自动用零来填充。


import numpy as np


def resize_array(array, new_size):
    Z = np.zeros(new_size)
    for i in range(len(Z)):
        for j in range(len(Z[i])):
            try:
                Z[i][j] = array[i][j]
            except IndexError:       # just in case array[i][j] doesn't exist in the new size and should be truncated
                pass
    return Z


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

© www.soinside.com 2019 - 2024. All rights reserved.