NumPyで計算をするためのクラスndarray
は、多次元配列や行列を扱うためのデータ構造です。内部実装では、データ型によってサイズの異なる連続した1次元のメモリ領域が確保されます。
ndarrayのインスタンス変数shape
は、1次元のメモリ領域のどこに指定した多次元配列の要素があるのかを知る手がかりになります。
この記事では、shape
の使い方と読み方を解説します。
ndarray.shape
ndarrayのshapeは、各次元ごとの要素数を示します。
使い方は、Pythonインスタンスと同様arr.shape
としてプロパティにアクセスするだけです。
まずは配列の情報を取得してみます。
In [1]: import numpy as np
In [2]: a = np.array([5, 3, 8, 9])
In [3]: a
Out[3]: array([5, 3, 8, 9])
In [4]: a.shape
Out[4]: (4,)
reshape
関数で変換すると、shape
は指定した引数に合わせて変更されます。ndarray内部の実装では配列の要素はshape
しか変更されません。単に形状の情報だけ変化されているので高速に実行することができます。
reshape
関数について詳しくは以下の記事を参考にしてください。
配列を形状変換するNumPyのreshapeの使い方 /features/numpy-reshape.html
変更後のshape
は、要素数が同じであればreshape
で指定した引数と同じものに変換されているはずです。
In [5]: a = np.array([5, 3, 8, 9])
In [5]: b = a.reshape((2, 2))
In [6]: b
Out[6]:
array([[5, 3],
[8, 9]])
In [7]: b.shape
Out[7]: (2, 2)
また、shapeプロパティに代入すると、reshape
関数と同じように配列を変形することができます。
In [8]: a
Out[8]:
array([[5, 3],
[8, 9]])
In [9]: a.shape
Out[9]: (2, 2)
In [10]: a.shape = (4, 1)
In [11]: a
Out[11]:
array([[5],
[3],
[8],
[9]])
In [12]: c = np.arange(12).reshape((3, 4))
Out[12]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [13]: c.shape=(1, 12)
In [14]: c
Out[14]: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
In [15]: c.shape = (13,) # 要素数を誤るとエラーが返る。
---------------------------------------------------------------------------
(エラーメッセージが表示される)
ValueError: cannot reshape array of size 12 into shape (13,)
しかし、特に理由がない限りは明示的にreshape
関数を使用するほうが無難かと思います。
(R,)や(R,1)という表記について
(R,)
という表記は見慣れないかもしれません。Pythonでは要素数が1つのタプルはこのような表記になります。すなわち、ただの1次元配列のshape
は(R,)
のような使い方をする必要があります。一方、1次元配列を転置した縦ベクトルの場合、shape
は(R, 1)
となります。
In [15]: a = np.array([1,2,3,4,5]) # ただの1次元配列
In [16]: a.shape
Out[16]: (5,)
In [17]: b = np.array([[1], [2], [3], [4], [5]]) # 縦ベクトルのようにすると(R,1)の形になる。
In [18]: b.shape
Out[18]: (5, 1)