NumPy配列に次元を追加:np.newaxis と np.expand_dims() の使い方


 


データ分析や機械学習のタスクにおいて、NumPy配列の次元を操作する機会は頻繁に訪れます。特に、既存の配列に新しい次元を追加したい場合、np.newaxisnp.expand_dims() という2つの便利な機能が役立ちます。これらは、データをモデルに入力する際の前処理や、特定の計算を行う上で非常に重要です。

この記事では、np.newaxisnp.expand_dims() のそれぞれの使い方と、どのような場合にどちらを使うべきかについて、簡潔なコード例を交えながら詳しく解説します。


 

NumPy配列の次元を追加する目的

 

NumPy配列に新しい次元を追加する主な目的は以下の通りです。

  • 単一データのためのバッチ次元の追加: 機械学習モデルは通常、複数のデータをまとめて(バッチで)処理するように設計されています。単一のデータポイントをモデルに入力する際、バッチ次元を追加してモデルの入力要件に合わせる必要があります。

  • ブロードキャスト操作の準備: NumPyのブロードキャスト機能は、形状の異なる配列間での演算を可能にします。新しい次元を追加することで、ブロードキャストが適切に行われるように配列の形状を調整できます。

  • データの構造化: データの意味合いを明確にするため、あるいは特定の計算に適した形状にするために次元を追加することがあります。


 

np.newaxis の使い方

 

np.newaxis は、配列のインデックス付け(スライシング)と組み合わせて使用される特殊なオブジェクトです。これを使用すると、指定した位置に新しい次元(サイズが1の軸)を挿入できます。

 

np.newaxis を使った次元の追加

 

Python
 
import numpy as np

arr = np.array([1, 2, 3, 4])
print(f"元の配列: {arr}")
print(f"元の形状: {arr.shape}\n") # (4,)

# 末尾に新しい次元を追加 (行ベクトル化)
row_vec = arr[np.newaxis, :] # または arr[None, :]
print(f"末尾に次元を追加 (行ベクトル):\n{row_vec}")
print(f"新しい形状: {row_vec.shape}\n") # (1, 4)

# 先頭に新しい次元を追加 (列ベクトル化)
col_vec = arr[:, np.newaxis] # または arr[:, None]
print(f"先頭に次元を追加 (列ベクトル):\n{col_vec}")
print(f"新しい形状: {col_vec.shape}") # (4, 1)

実行結果:

元の配列: [1 2 3 4]
元の形状: (4,)

末尾に次元を追加 (行ベクトル):
[[1 2 3 4]]
新しい形状: (1, 4)

先頭に次元を追加 (列ベクトル):
[[1]
 [2]
 [3]
 [4]]
新しい形状: (4, 1)

np.newaxis は、スライス操作のどの位置に挿入するかによって、新しい次元が追加される位置が変わります。: は既存の次元をそのまま保持することを意味します。


 

np.expand_dims() の使い方

 

np.expand_dims() は、関数として提供されており、配列と新しい次元を追加する軸のインデックスを引数に取ります。より明示的に次元追加を行いたい場合に便利です。

 

np.expand_dims() を使った次元の追加

 

Python
 
import numpy as np

arr = np.array([1, 2, 3, 4])
print(f"元の配列: {arr}")
print(f"元の形状: {arr.shape}\n") # (4,)

# 軸0 (先頭) に新しい次元を追加
expanded_arr_axis0 = np.expand_dims(arr, axis=0)
print(f"軸0に次元を追加:\n{expanded_arr_axis0}")
print(f"新しい形状: {expanded_arr_axis0.shape}\n") # (1, 4)

# 軸1 (末尾) に新しい次元を追加
expanded_arr_axis1 = np.expand_dims(arr, axis=1)
print(f"軸1に次元を追加:\n{expanded_arr_axis1}")
print(f"新しい形状: {expanded_arr_axis1.shape}") # (4, 1)

実行結果:

元の配列: [1 2 3 4]
元の形状: (4,)

軸0に次元を追加:
[[1 2 3 4]]
新しい形状: (1, 4)

軸1に次元を追加:
[[1]
 [2]
 [3]
 [4]]
新しい形状: (4, 1)

axis 引数は、新しい次元が挿入される位置を指定します。axis=0 は最も外側の次元(先頭)、axis=1 はその次の次元(2番目の位置)などとなります。


 

np.newaxisnp.expand_dims() の使い分け

 

両者とも同様の目的を果たしますが、使いやすさやコードの意図の表現方法に違いがあります。

特徴 np.newaxis np.expand_dims()
形式 配列のインデックス付けに埋め込む特殊オブジェクト NumPy関数
表現 簡潔でコンパクト。スライス操作の一部として自然。 明示的で分かりやすい。特に複数の次元を追加する場合。
柔軟性 複数の新しい次元を同時に追加可能。 一度に一つの次元しか追加できないが、複数回呼び出しで対応可能。
ユースケース 既存のスライス操作と組み合わせて直感的に使いたい場合。 どのような次元が追加されるかをより明確に示したい場合。スクリプトや関数内で動的に軸を指定する場合。

 

どちらを選ぶべきか?

 

  • 簡潔さを重視し、特定の場所に新しい次元を1つ追加したい場合np.newaxis が非常に便利です。特に、行ベクトルや列ベクトルへの変換など、よくあるパターンに適しています。

  • コードの可読性を重視し、新しい次元が追加される軸を明示的に指定したい場合np.expand_dims() がおすすめです。axis 引数によって意図が明確になり、スクリプト内で動的に次元追加位置を変える際にも役立ちます。

どちらを使っても最終的な結果は同じですが、プロジェクトのコーディング規約や個人の好みに合わせて選択すると良いでしょう。


 

まとめ

 

NumPy配列に次元を追加する np.newaxisnp.expand_dims() は、データの前処理やモデル入力の準備において不可欠なツールです。それぞれの特徴と使い分けを理解することで、NumPyをより効果的に活用し、データ操作の幅を広げることができます。