1. ホーム
  2. python

[解決済み] python how to pad numpy array with zeros (numpy配列をゼロで埋める)

2022-03-04 06:09:20

質問

python 2.6.6とnumpyバージョン1.5.0を使用して、2Dのnumpy配列をゼロで埋める方法を知りたいです。しかし、これらは私の限界です。したがって、私は使用できません np.pad . 例えば、私は a に一致するようにゼロを挿入します。 b . ということができるようにしたいからです。

b-a

そのような

>>> a
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
>>> b
array([[ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.]])
>>> c
array([[1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 0],
       [0, 0, 0, 0, 0, 0]])

これを行う唯一の方法は追加することですが、これはかなり醜いように思われます。 b.shape ?

編集 MSeifertsの回答ありがとうございました。少し整理したら、こんな感じになりました。

def pad(array, reference_shape, offsets):
    """
    array: Array to be padded
    reference_shape: tuple of size of ndarray to create
    offsets: list of offsets (number of elements must be equal to the dimension of the array)
    will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets
    """

    # Create an array of zeros with the reference shape
    result = np.zeros(reference_shape)
    # Create a list of slices from offset to offset + shape in each dimension
    insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]
    # Insert the array in the result at the specified offsets
    result[insertHere] = array
    return result

解決方法は?

非常に簡単で、参照形状を利用してゼロを含む配列を作成します。

result = np.zeros(b.shape)
# actually you can also use result = np.zeros_like(b) 
# but that also copies the dtype not only the shape

を作成し、必要な場所に配列を挿入します。

result[:a.shape[0],:a.shape[1]] = a

で、ほら、水増し完了です。

print(result)
array([[ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])


また、左上の要素がどこに挿入されるべきかを定義すれば、もう少し一般的にすることができます。

result = np.zeros_like(b)
x_offset = 1  # 0 would be what you wanted
y_offset = 1  # 0 in your case
result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a
result

array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.,  1.,  1.]])

ただし、オフセットが許容値より大きくならないように注意してください。例えば x_offset = 2 のようにすると失敗します。


もし任意の次元数があれば、元の配列を挿入するためのスライスのリストを定義することができます。私は少し遊んでみて、配列と参照が同じ次元数でオフセットが大きすぎない限り、任意の形状の配列を(オフセットを伴って)パディングできるパディング関数を作成しました。

def pad(array, reference, offsets):
    """
    array: Array to be padded
    reference: Reference array with the desired shape
    offsets: list of offsets (number of elements must be equal to the dimension of the array)
    """
    # Create an array of zeros with the reference shape
    result = np.zeros(reference.shape)
    # Create a list of slices from offset to offset + shape in each dimension
    insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)]
    # Insert the array in the result at the specified offsets
    result[insertHere] = a
    return result

そして、いくつかのテストケース。

import numpy as np

# 1 Dimension
a = np.ones(2)
b = np.ones(5)
offset = [3]
pad(a, b, offset)

# 3 Dimensions

a = np.ones((3,3,3))
b = np.ones((5,4,3))
offset = [1,0,0]
pad(a, b, offset)