簡體   English   中英

如何有效地將 numpy 數組調整為給定形狀,必要時用零填充?

[英]How to efficiently resize a numpy array to a given shape, padding with zeros if necessary?

我想基於另一個 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]
])

我想我通過下面的 function 實現了預期的行為。

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 元組操作。 有沒有更好更簡潔的方法呢?

如果您知道您的數組不會大於某個大小(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

並支持更大的 arrays (比您要填充的更大):

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

我不認為你可以做得更好,但不要使用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.]])

我只需使用零矩陣並運行嵌套的 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)))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM