[Python numpy] numpy 배열에서 특정 형상의 빈 자리를 0으로 채우기 (padding)
Python 분석과 프로그래밍/Python 데이터 전처리 2020. 9. 11. 00:541. numpy 배열을 특정 형상의 배열로 변형할 때 빈자리를 '0'으로 채우기 (padding) : numpy.pad() 함수 |
먼저, numpy 라이브러리를 importing 하고, 예제로 사용할 2 by 3 의 간단한 2차원 배열(array)을 만들어보겠습니다.
import numpy as np x = np.array([[1, 2, 3], array([[1, 2, 3],
[7, 2, 5]]) |
numpy.pad(array, pad_width, mode='constant', **kwargs)
# np.pad(x, (1, 1)) np.pad(x, (1, 1),
|
np.pad(x, (1, 2), array([[0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 0, 0], [0, 7, 2, 5, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
|
z = np.zeros((4, 5)) [[0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.]]
|
np.pad(x, (1, 1), constant_values=-1) array([[-1, -1, -1, -1, -1], [-1, 1, 2, 3, -1], [-1, 7, 2, 5, -1], [-1, -1, -1, -1, -1]]) |
빈 자리 채워넣기하는 방법(mode)에는 항상 똑같은 상수('constant', default) 값을 채워넣는 방법 외에도 'edge', 'linear_ramp', 'maximum', 'mean', 'median', reflect', 'symmetric', 'wrap', 'empty' 등의 다양한 mode 옵션을 제공합니다. 이들 중에서 위의 예시에서 사용한 'constant' 이외에 'edge', 'maximum', 'wrap' 의 mode 옵션을 사용하여 채워넣기 padding을 해보겠습니다. (아래 결과에서 빨간색으로 표시한 부분이 padding된 부분입니다.)
- mode = 'edge' : 가장 변두리의 원소 값으로 빈 곳 채우기
np.pad(x, (1, 1), mode='edge')
|
- mode = 'maximum' : 행과 열의 가장 큰 값으로 빈 곳 채우기
np.pad(x, (1, 1), mode='maximum') array([[7, 7, 2, 5, 7], [3, 1, 2, 3, 3], [7, 7, 2, 5, 7], [7, 7, 2, 5, 7]]) |
- mode = 'wrap' : 행과 열의 반대편 끝에 있는 원소 값으로 빈 곳 채우기
np.pad(x, (1, 1), mode='wrap') array([[5, 7, 2, 5, 7], [3, 1, 2, 3, 1], [5, 7, 2, 5, 7], [3, 1, 2, 3, 1]]) |
2. 원소 개소가 다른 Ragged array를 특정 형상의 배열로 바꿀 때 빈자리를 '0'으로 채우기 : tensorflow.keras.preprocessing.sequence.pad_sequence() 함수 |
위의 np.pad() 함수의 경우 변경하기 전의 원래 배열이 (m by n) 형상인 고정된 차원의 배열을 대상으로 채워넣기를 하였습니다. 두번째로 소개하려는 keras의 sequence.pad_sequence() 함수는 각 행의 원소 개수가 다른 Ragged array(?) 를 대상으로 특정 (j by k) 형상의 고정된 배열로 바꾸려고 할 때 빈 자리를 '0'으로 채워넣는데 사용할 수 있는 차이가 있습니다.
아래의 예를 보면 원소 개수가 1개, 2개, 3개, 4개로서 들쭉날쭉함을 알 수 있습니다. (list를 원소로 가지고 있고, data type 이 object 이네요.)
x2 = np.array([[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]) array([list([1]),
|
TensorFlow와 Keras의 tf.keras.preprocessing.sequence() 메소드를 importing 해보겠습니다.
import tensorflow as tf 2.3.0
|
tf.keras.preprocessing.sequence.pad_sequences(sequences, maxlen=None, dtype='int32',padding='pre', truncating='pre',value=0.0)
sequence.pad_sequences(x2) # default: padding='pre', value=0 array([[ 0, 0, 0, 1], [ 0, 0, 2, 3], [ 0, 4, 5, 6], [ 7, 8, 9, 10]], dtype=int32)
|
sequence.pad_sequences(x2, padding='post') array([[ 1, 0, 0, 0], [ 2, 3, 0, 0], [ 4, 5, 6, 0], [ 7, 8, 9, 10]], dtype=int32)
|
물론 빈 곳 채워넣기(padding)하는 값을 '0'이 아니라 다른 값으로 할 수도 있습니다. '-1'을 사용(value=-1)해서 앞쪽에 빈 곳을 채워넣기해보겠습니다.
sequence.pad_sequences(x2, padding='pre', value=-1) array([[-1, -1, -1, 1], [-1, -1, 2, 3], [-1, 4, 5, 6], [ 7, 8, 9, 10]], dtype=int32)
|
sequence.pad_sequences(x2, padding='pre', value=0, maxlen=5) array([[ 0, 0, 0, 0, 1], [ 0, 0, 0, 2, 3], [ 0, 0, 4, 5, 6], [ 0, 7, 8, 9, 10]], dtype=int32) |
sequence.pad_sequences(x2, padding='pre', value=0, maxlen=3, truncating='post') array([[0, 0, 1],
[0, 2, 3],
[4, 5, 6],
[7, 8, 9]], dtype=int32) |