NumPy配列ndarrayをシフト(スクロール)させるnp.roll

NumPyの関数np.roll()を使うとNumPy配列ndarrayをシフト(スクロール)させることができます。配列の開始位置をずらすときなどに使います。

numpy.roll — NumPy v1.16 Manual

ここでは以下の内容について説明します。

np.roll()の基本的な使い方 二次元配列(多次元配列)の場合 画像処理への応用(画像をスクロール)

np.roll()の基本的な使い方

一次元配列を例とします。

import numpy as np

a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]

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]

ビューではなくコピーを返すので新たな配列の要素を変更しても元の配列の要素はそのまま。

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]

第二引数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

二次元配列(多次元配列)の場合

多次元配列の場合、デフォルトでは一次元化されてからシフトされ元の形状に戻される。 二次元配列を例とすると以下の通り。

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]]

第三引数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]]

第二引数shiftと第三引数axisにタプルで複数の値を指定すると、複数の軸に沿ってシフトさせることも可能。

print(np.roll(a_2d, (1, 2), axis=(0, 1)))
# [[10 11  8  9]
#  [ 2  3  0  1]
#  [ 6  7  4  5]]

さらに次元数が多い場合も同様。以下は三次元配列の例。

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]]]

画像処理への応用(画像をスクロール)

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')

元の画像。

スクロールさせた画像。

シェア

関連カテゴリー

Python NumPy 画像処理

Pythonでの画像処理、Pillow, NumPy, OpenCVの違いと使い分け Python, OpenCV, Pillow(PIL)で画像サイズ(幅、高さ)を取得 NumPyでRGB画像の色チャンネルを分離して単色化、白黒化、色交換 NumPy配列ndarrayをタイル状に繰り返し並べるnp.tile Python, OpenCV, NumPyで画像のアルファブレンドとマスク処理 Python, NumPy(OpenCV)で画像を二値化処理 Python, NumPyで画像処理(読み込み、演算、保存) Python, NumPyでグラデーション画像を生成 Python, Pillowで画像を回転するrotate NumPyの配列ndarrayの欠損値np.nanを他の値に置換 NumPyのsortとargsort関数で任意の行・列を基準にソート NumPyで欠損値np.nanを含む配列ndarrayの合計や平均を算出 NumPy配列ndarrayをイミュータブル(書き換え禁止)に設定 NumPy配列ndarrayとPython標準のリストを相互に変換 Python, OpenCVで顔検出と瞳検出(顔認識、瞳認識)

Last Updated: 6/26/2019, 10:34:03 PM