NumPy配列を自在にシフト!np.rollでデータをスクロールさせる方法


 

データ分析や信号処理、画像処理など、さまざまな分野でNumPy配列の要素を循環的に移動させたい(シフトまたはスクロールさせたい)場面があります。例えば、時系列データを過去にずらしたり、画像を回転させずに端から端へ移動させたりするケースです。このようなニーズに応えるのが、NumPyの**np.roll()関数です。この記事では、np.roll()を使ってNumPy配列の要素を効率的にシフト(スクロール)させる方法**について、具体的なサンプルコードを交えながら詳しく解説します。


 

np.roll()とは?

 

np.roll()は、NumPy配列の要素を指定された軸に沿って循環的にシフトさせる(転がす、スクロールさせる)関数です。配列の端に到達した要素は、反対側の端から再び現れます。

 

書式

 

Python
 
numpy.roll(a, shift, axis=None)
  • a: シフトさせたい入力配列(ndarray)。

  • shift: 各軸に沿ってシフトさせる量。

    • 正の値: 右方向(または下方向)にシフト。

    • 負の値: 左方向(または上方向)にシフト。

    • 単一の整数: 配列全体をフラットにした状態でシフト。

    • タプル: 各軸に対して異なるシフト量を指定。

  • axis (オプション): シフトを行う軸を指定します。

    • None (デフォルト): 配列全体を1次元に平坦化してシフト。

    • 整数または整数のタプル: 指定された軸(複数可)に沿ってシフト。


 

1. 1次元配列のシフト

 

最も基本的な使い方は、1次元配列の要素を左右にシフトさせる場合です。

 

サンプルコード

 

Python
 
import numpy as np

arr_1d = np.array([1, 2, 3, 4, 5])
print("元の配列:", arr_1d)

# 右に2つシフト
rolled_right = np.roll(arr_1d, 2)
print("右に2つシフト:", rolled_right)

# 左に1つシフト (負の値を指定)
rolled_left = np.roll(arr_1d, -1)
print("左に1つシフト:", rolled_left)

 

出力例

 

元の配列: [1 2 3 4 5]
右に2つシフト: [4 5 1 2 3]
左に1つシフト: [2 3 4 5 1]

 

2. 多次元配列のシフト(axisの指定)

 

np.roll()の強力な点は、多次元配列の特定の軸に沿ってシフトできることです。

 

2-1. 特定の軸(行または列)に沿ってシフト

 

axis引数に整数を指定することで、その軸に沿って要素をシフトできます。

 

サンプルコード

 

Python
 
import numpy as np

arr_2d = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])
print("元の2D配列:\n", arr_2d)

# axis=0: 列方向(縦方向)にシフト
# 各列の要素が循環的に移動
rolled_axis0 = np.roll(arr_2d, 1, axis=0)
print("\naxis=0(縦方向)に1つシフト:\n", rolled_axis0)

# axis=1: 行方向(横方向)にシフト
# 各行の要素が循環的に移動
rolled_axis1 = np.roll(arr_2d, -1, axis=1)
print("\naxis=1(横方向)に-1つシフト:\n", rolled_axis1)

 

出力例

 

元の2D配列:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]

axis=0(縦方向)に1つシフト:
 [[7 8 9]
 [1 2 3]
 [4 5 6]]

axis=1(横方向)に-1つシフト:
 [[2 3 1]
 [5 6 4]
 [8 9 7]]

 

2-2. 複数の軸を同時に異なる量でシフト

 

shiftaxisの両方にタプルを指定することで、複数の軸を異なる量で同時にシフトできます。

 

サンプルコード

 

Python
 
import numpy as np

arr_2d = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])
print("元の2D配列:\n", arr_2d)

# axis=0を1つ、axis=1を-1つシフト
rolled_multi_axis = np.roll(arr_2d, shift=(1, -1), axis=(0, 1))
print("\n複数の軸をシフト (axis=0を1, axis=1を-1):\n", rolled_multi_axis)

 

出力例

 

元の2D配列:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]

複数の軸をシフト (axis=0を1, axis=1を-1):
 [[8 9 7]
 [2 3 1]
 [5 6 4]]

 

3. 画像処理での応用例

 

np.roll()は、画像処理において、画像を回転させずに平行移動させる(スクロールさせる)場合などに利用できます。

 

サンプルコード(画像をスクロール)

 

Python
 
import numpy as np
from PIL import Image

# ダミー画像を生成 (青色の200x200画像)
img_np = np.zeros((200, 200, 3), dtype=np.uint8)
img_np[:,:] = [255, 0, 0] # 青 (BGR/RGBどちらでも動くように)
img_np[50:150, 50:150] = [0, 255, 0] # 中央に緑の四角

# 画像を右に50ピクセル、下に20ピクセルシフト
# axis=(1, 0) で (幅, 高さ) の順
shifted_img_np = np.roll(img_np, shift=(20, 50), axis=(0, 1))

# Pillowで画像として保存
img_pil = Image.fromarray(shifted_img_np)
img_pil.save('shifted_image.png')
print("シフトした画像を 'shifted_image.png' として保存しました。")

 

まとめ

 

NumPyのnp.roll()関数は、配列の要素を循環的にシフト(スクロール)させるための非常に便利で効率的なツールです。

  • 1次元配列: shift引数で左右に要素を移動させます。

  • 多次元配列: axis引数で特定の軸(行、列など)に沿ってシフトできます。shiftaxisにタプルを指定することで、複数の軸を異なる量で同時にシフトすることも可能です。

  • 応用範囲: 時系列データの操作、画像処理(画像の平行移動)、シミュレーションなど、多岐にわたる分野で活用できます。

np.roll()を使いこなすことで、複雑なデータの移動処理を簡潔かつ高速に記述できるようになります。ぜひ、あなたのNumPyワークフローに取り入れてみてください!🌀