こんにちは!この記事ではnp.ravelという関数を紹介します!
flattenという関数、他の様々なプログラミング言語に実装されている機能で、「多次元配列を一次元配列に変換する」という機能を持ちます。
もちろんNumPyにもflattenはあるのですが、この記事では場合によってflattenよりも高速に動作するnp.ravel関数について紹介します。
この記事の要点は
- np.ravelはflattenと同様に多次元配列を一次元配列に変換する関数である
- np.ravelは元の配列への参照を返すためメモリ効率がよく高速
の二点です。
この解説にピンと来なかった方、この記事でnp.ravelについて勉強しましょう!
np.ravelの使い方
※この記事のコードは、jupyter notebookやjuputer labを使って書かれています。
コードを試すときは是非これらを使ってみてください。
ravelはnp.ravelとしても、ndarray(np.array)のメソッドとしても実装されています。どちらを使っても使い方はほぼ同じなので、書きやすい方を使ってください。
# コード In [1]: import numpy as np
# コード In [2]: a = np.arange(12).reshape(4,-1) a
# 出力結果 Out [2]: array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
この多次元配列aを一次元配列に直してみましょう。
使い方は簡単、ndarrayオブジェクト.ravel()とするか、np.ravel(ndarrayオブジェクト)とするかです。
# コード In [3]: b = a.ravel() b
# 出力結果 Out [3]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
# コード In [4]: c = np.ravel(a) c
# 出力結果 Out [4]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
# コード In [5]: print("a: original") print(a) print("\nb") print(b) print("\nc") print(c)
# 出力結果 [5]: a: original [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] b [ 0 1 2 3 4 5 6 7 8 9 10 11] c [ 0 1 2 3 4 5 6 7 8 9 10 11]
ravelとflattenの違い
ravelは元の配列へのビューを返す関数
flattenも同じように多次元配列を一次元配列に変換してくれました。
flattenで一次元配列にしたときは、返り値の配列の要素を変更しても元の配列は変わりません。それに対して、実はravelは返り値の配列を変更すると元の配列の要素も変わってしまいます。
# コード In [6]: b[0] = 100
# コード In [7]: print("a: original") print(a) print("\nb") print(b) print("\nc") print(c)
# 出力結果 [7]: a: original [[100 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] b [100 1 2 3 4 5 6 7 8 9 10 11] c [100 1 2 3 4 5 6 7 8 9 10 11]
flattenとの明確な差はここだけだと思います。元の配列が変わってしまっても大丈夫な時、ravelを使えばOKです。
flattenはravelより遅い
flattenはravelより動作が遅いです。これはravelが元の配列を返しているのに対して、flattenは新しい配列を作っているから、というのが大きな原因です。
これについて、flattenの記事で速度比較を行いましたので、チェックしてみてください!
まとめ
この記事では、多次元配列を一次元配列に変換するnp.ravel関数について紹介しました。
ravelは高速で動作するメモリ効率のいい関数です。多次元配列を一次元配列に、という変換は画像処理(CNNやSVMなどを使った画像分類など)でもよく使う機能なので、是非使ってみてください!