行列計算では、配列のshape(形)が非常に重要になります。numpy.array(配列)のshapeを変える方法はいろいろありますが、np.reshapeが最も柔軟で簡単な関数です。
この記事では、そんなnp.reshapeの使い方を解説します。
np.reshapeの引数と返り値
np.reshapeの主な引数と返り値の解説です。
numpy.
reshape
(a, newshape, order=’C’)
データ(配列の要素)は変更せずに、配列を新しい形状にします。
Parameters: |
|
---|---|
Returns: |
|
使い方
ここから先のサンプルコードは、全てJupyterの上で試しています。
In以下のコードはJupyterのセルに書くコードで、Out以下は直前のInに書かれたコードの出力結果です。
まずはnumpyをimportします。
In [1]:
import numpy as np
そして配列の情報を確認するための関数を用意します。
def array_info(x):
print("配列のshape", x.shape)
print("配列の要素のデータ型", x.dtype)
print("配列の中身n",x)
ではまず、reshape対象の配列を用意しましょう。
x = np.arange(0,12)
array_info(x)
Out:
基本的な使い方
np.reshapeの第二引数として使えるshape(配列の形)は、新しいshapeの積が元のshapeの積と同じ値になるように指定します。
例えば、ここで、xを別の形に変えようと思った時、
前の配列のshapeの積 = 新しい配列のshapeの積 (12,) = (3, 4) 12 = 3 × 4
となっていればOKです。
flatten関数のように、多次元配列を一次元配列に展開することもできます。
size = np.prod(x3.shape)
x4 = np.reshape(x3, size)
print(x3.shape, "->", size)
array_info(x4)
Out:
flatten, ravelとの速度比較
flattenやravelという関数は、多次元配列を一次元配列に展開する機能を持ちます。
これらとreshapeとの速度比較をしてみましょうjupyterではcellの先頭に%%timeitをつけることで計算時間を計測できます。
%%timeit
size = np.prod(x3.shape)
x4 = np.reshape(x3, size)
[計算時間]
%%timeit
x4 = np.reshape(x3, size)
[計算時間]
%%timeit
x4 = x3.flatten()
[計算時間]
%%timeit
x4 = x3.ravel()
[計算時間]
残念ながらreshapeが一番遅く、次にflatten、一番早いのがravelになります。
ravelは元の配列への参照を返しているので、形を変えた方の配列の要素を変更すると、元の配列の方も変更されてしまうので注意が必要です。
reshape(-1)で配列のshapeを自動設定
np.reshapeのshapeの計算、楽をすることもできます。
例えば、(12,)を(2, 6)にしたい時。変更後の配列の形、片方を設定して上げれば残りは-1と書くだけで勝手にshapeを最適なものにしてくれます。実際に見てみましょう。
In [11]:
x5 = np.reshape(x3, (2,-1)) array_info(x5)
Out:
配列のshape (2, 6) 配列の要素のデータ型 int64 配列の中身 [[ 0 1 2 3 4 5] [ 6 7 8 9 10 11]]
まとめ
この記事では、numpy.arrayのshapeを変える(配列の形を変える)関数、np.reshapeについて紹介しました。ニューラルネットワークなどの計算では、配列の形が揃っていないと計算ができないといったことがあります。
そんなときにnp.reshapeは非常に有用な関数です。この記事でnp.reshapeの使い方を覚えて、是非科学計算や機械学習の実装に役立ててください!
今回の記事は下記の記事を参考にしています。
参考記事: