NumPy配列ndarrayをシフト(スクロール)させるnp.roll
NumPyの関数np.roll()
を使うとNumPy配列ndarray
をシフト(スクロール)させることができる。配列の開始位置をずらすときなどに使う。
ここでは以下の内容について説明する。
np.roll()
の基本的な使い方- 二次元配列(多次元配列)の場合
- 画像処理への応用(画像をスクロール)
np.roll()の基本的な使い方
一次元配列を例とする。
import numpy as np
a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
source: numpy_roll.py
np.roll()
の第一引数a
に元のndarray
、第二引数shift
にシフトさせる要素数を指定する。新たな配列が返され、元の配列自体は変更されない。
a_roll = np.roll(a, 3)
print(a_roll)
# [7 8 9 0 1 2 3 4 5 6]
print(a)
# [0 1 2 3 4 5 6 7 8 9]
source: numpy_roll.py
ビューではなくコピーを返すので新たな配列の要素を変更しても元の配列の要素はそのまま。
a_roll[0] = 100
print(a_roll)
# [100 8 9 0 1 2 3 4 5 6]
print(a)
# [0 1 2 3 4 5 6 7 8 9]
source: numpy_roll.py
第二引数shift
には負の値や全体の要素数を超える値も指定可能。整数int
でないとエラーになる。
print(np.roll(a, -3))
# [3 4 5 6 7 8 9 0 1 2]
print(np.roll(a, 12))
# [8 9 0 1 2 3 4 5 6 7]
# print(np.roll(a, 0.5))
# TypeError: slice indices must be integers or None or have an __index__ method
source: numpy_roll.py
二次元配列(多次元配列)の場合
多次元配列の場合、デフォルトでは一次元化されてからシフトされ元の形状に戻される。
二次元配列を例とすると以下の通り。
a_2d = np.arange(12).reshape(3, 4)
print(a_2d)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(np.roll(a_2d, 2))
# [[10 11 0 1]
# [ 2 3 4 5]
# [ 6 7 8 9]]
print(np.roll(a_2d, 5))
# [[ 7 8 9 10]
# [11 0 1 2]
# [ 3 4 5 6]]
source: numpy_roll.py
第三引数axis
に軸を指定すると、その軸に沿ってシフトされる。
print(np.roll(a_2d, 1, axis=0))
# [[ 8 9 10 11]
# [ 0 1 2 3]
# [ 4 5 6 7]]
print(np.roll(a_2d, 2, axis=1))
# [[ 2 3 0 1]
# [ 6 7 4 5]
# [10 11 8 9]]
source: numpy_roll.py
第二引数shift
と第三引数axis
にタプルで複数の値を指定すると、複数の軸に沿ってシフトさせることも可能。
print(np.roll(a_2d, (1, 2), axis=(0, 1)))
# [[10 11 8 9]
# [ 2 3 0 1]
# [ 6 7 4 5]]
source: numpy_roll.py
さらに次元数が多い場合も同様。以下は三次元配列の例。
a_3d = np.arange(24).reshape(2, 3, 4)
print(a_3d)
# [[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
#
# [[12 13 14 15]
# [16 17 18 19]
# [20 21 22 23]]]
print(np.roll(a_3d, 3))
# [[[21 22 23 0]
# [ 1 2 3 4]
# [ 5 6 7 8]]
#
# [[ 9 10 11 12]
# [13 14 15 16]
# [17 18 19 20]]]
print(np.roll(a_3d, 2, axis=2))
# [[[ 2 3 0 1]
# [ 6 7 4 5]
# [10 11 8 9]]
#
# [[14 15 12 13]
# [18 19 16 17]
# [22 23 20 21]]]
source: numpy_roll.py
画像処理への応用(画像をスクロール)
np.roll()
を利用するとNumPy配列ndarray
として読み込んだ画像をスクロールさせることができる。
画像の読み込みや保存などNumPyを使った画像処理の基礎については以下の記事を参照。
縦・横にスクロールさせる例を以下に示す。ここではPillowを使って画像ファイルを読み込んでいるが、ndarray
として読み込むのであればOpenCVなど他のライブラリを使っても同じ。
import numpy as np
from PIL import Image
img = np.array(Image.open('data/src/lena.jpg'))
print(img.shape)
# (225, 400, 3)
img_scroll = np.roll(img, (50, 100), axis=(0, 1))
Image.fromarray(img_scroll).save('data/dst/lena_numpy_roll.jpg')
source: numpy_roll_image.py
元の画像。
スクロールさせた画像。