零填充二维数组上的 Numpy 切片

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

给定一个 2D Numpy 数组,我希望能够将其填充到左侧、右侧、顶部、底部,如下面的伪代码所示。 Numpy 中已经内置了类似的东西吗?

import numpy as np

a = np.arange(16).reshape((4, 4))
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]

pad(a)[-4:2, -1:3]   # or any syntax giving the same result

#[[0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]
# [0 0 0 0]
# [0 0 1 2]
# [0 4 5 6]]

pad(a)[-4:2, -1:6]

#[[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 0 0]
# [0 0 1 2 3 0 0]
# [0 4 5 6 7 0 0]]
python numpy multidimensional-array padding numpy-ndarray
2个回答
1
投票

您不能为此使用切片,负数在切片中具有不同的含义。

你必须使用

pad

np.pad(a[:2, :3], ((4, 0), (1, 0)), constant_values=0)

array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 1, 2],
       [0, 4, 5, 6]])

np.pad(a[:2, :], ((4, 0), (1, 6-a.shape[1])), constant_values=0)

array([[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, 0, 0],
       [0, 0, 1, 2, 3, 0, 0],
       [0, 4, 5, 6, 7, 0, 0]])

使用函数的通用方法:

def pad(a, top=0, bottom=0, left=0, right=0):
    T = max(top, 0)
    B = min(bottom, a.shape[0])
    L = max(left, 0)
    R = min(right, a.shape[1])
    pT = -min(top, 0)
    pB = max(bottom-a.shape[0], 0)
    pL = -min(left, 0)
    pR = max(right-a.shape[1], 0)
    return np.pad(a[T:B, L:R], ((pT, pB), (pL, pR)), constant_values=0)

pad(a, -4, 2, -1, 3)

array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 1, 2],
       [0, 4, 5, 6]])

pad(a, -4, 2, -1, 6)

array([[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, 0, 0],
       [0, 0, 1, 2, 3, 0, 0],
       [0, 4, 5, 6, 7, 0, 0]])

0
投票

您可以定义一个正确大小的零数组,然后从数组中复制切片:

def pad(array: np.ndarray, row_slice: tuple[int], col_slice: tuple[int]) -> np.ndarray:
    arows, acols = array.shape
    
    take_rows = slice(max(0, row_slice[0]), min(arows, row_slice[1]))
    take_cols = slice(max(0, col_slice[0]), min(acols, col_slice[1]))
    take_arr = array[take_rows, take_cols]
    t_start_row = abs(min(0, row_slice[0]))
    t_start_col = abs(min(0, col_slice[0]))

    rrows = row_slice[1] - row_slice[0]
    rcols = col_slice[1] - col_slice[0]

    z = np.zeros((rrows, rcols))
    z[t_start_row:t_start_row + take_arr.shape[0], t_start_col:t_start_col + take_arr.shape[1]] = take_arr

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