NumPyのndarrayは、NumPy操作をするための多次元配列です。多次元の構造はndarray.shape
で確認することができます。
多次元構造を操作するために必須となるのが、軸(axis)を正しく理解することです。多次元の配列構造を処理するために、NumPyの関数の引数には、axis
を指定することが出来る場面が多々あります。
他の記事において、要素の合計を計算するnp.sum
関数、要素の平均を計算するnp.average
関数、最大の要素を探すnp.amax
関数などを紹介してきましたが、それぞれの関数の中で引数としてaxis
があります。
これは配列の軸にあたるものですがどの軸がどの次元に対応しているのか分かりにくいことが多いです。
そのため、本記事では、
- 次元数とはなにか
- 軸(axis)とは何か
- 関数の引数としてaxisを指定すると何が起きているのか
について解説していきます。
ndarrayの次元数(ndim)とは何か
NumPyの多次元配列であるndarrayは、.shape
でその構造を把握することができます。
上記のコードの場合、shape
を見ると2×3の構造をしていることが分かります。shape
についての詳しい解説は以下の記事を参考にしてください。
NumPyのndarrayのインスタンス変数shapeの意味 /features/numpy-shape.html
ndim
は多次元配列が何次元の構造をしているのかを意味しています。つまり、shape
の要素の数なのでlen(arr.shape)
ということになります。
axisについて
axis
は名前の通り、座標軸のようなものです。どの軸かを指定するための方法として、axis
はshape
のインデックスに対応します。
3×2の行列を考えてみます。
上記のa
という多次元配列は3×2の行列なので、shape
は(3, 2)
です。NumPyのndarrayはネストした配列になっていますが、ネストの上位順にshape
の要素は並びます。
3×2の行列の場合、プリミティブな要素だけ入っている配列は、上図のように列方向になります。そして、より上位の配列なのは行方向です。つまり、軸順は(行方向, 列方向)
となります。
3次元に拡張してみましょう。この3×2の行列を複数持つ配列を新しく作ることになるので、新しい軸はshape
の先頭に相当します。分かりやすくするために、作成したa
を2つ含む配列を作成してみます。
この場合、以下の図のように3×2の多次元配列を持つ配列をつくったので、新しく出来た最上位のaxis
が0になります。
関数の引数としてのaxis
NumPyには、axis
を引数にとる関数が少なくありません。ndarray.sum
では、axisを指定して合計を計算することができます。その結果出力されるshape
は指定した軸方向に次元削減されることになります。
上記のb
配列を例にすると、
b.shape == (2, 3, 2)
ですが、sum
関数の出力shape
は以下のようになります。
b.sum(axis=0).shape == (3, 2)
b.sum(axis=1).shape == (2, 2)
b.sum(axis=2).shape == (2, 3)
図示しながら確認してみましょう。axis=0
を引数に取った場合、下図のaxis=0方向の矢印に向かって要素が足し合わされます。
0軸方向には、同じ値が2つ並んでいるので、各要素が2倍されるはずです。
期待通りの結果になりました。axis=1
にして確認してみます。この場合は、下図のように行方向に足し合わされることになります。
どうなるか結果は想像できましたか?実際に確認してみます。
行方向の要素が次元毎に足し合わされて、期待通りの結果になりました。axis=2
の場合も確認してみます。下図のように列方向に足し合わされるはずです。
予想どおりでしたか?列方向に各要素が足し合わされて次元削減されました。
NumPyのaxis
はshape
のインデックスです。是非NumPyの操作方法を覚えて使いこなしてください。