HOWTO · NumPy
NumPy で行列を配列に変換する
このチュートリアルでは、Python で行列を配列に変換する方法を示します
このページの内容
np.asarray() または np.array() を使うと、行列の次元を保ったまま NumPy の ndarray に変換できます。1次元の結果を作るには、配列に対して flatten()、ravel()、または reshape(-1) を呼び出します。後から結果を変更する場合は、方法の選択が重要です。flatten() は常にコピーを作成しますが、ravel() と reshape(-1) は、メモリ配置が許せば元のデータを共有することがあります。
次の例では、Pythonのリストのリストを配列に変換し、1次元配列を作る3つの方法を比較します。また、平坦化した結果への書き込みが元の配列とどう関係するかも示します。この例は実行済みです。出力から、2次元の形状が保たれることと、平坦化したコピーを変更しても元の配列は変わらないことを確認できます。
行列を2次元のNumPy配列に変換する
入れ子のリストの場合、np.asarray(matrix) は同じ2次元形状の配列を作成します。np.array(matrix) も直接変換する方法です。どちらも入れ子構造から次元を推定しますが、どちらも「平坦化」を意味する呼び出しではありません。既存の ndarray については、変換が不要なら np.asarray() はその配列自体を返すことがありますが、np.array() は既定でコピーを作成します。独立した配列が必要な場合は後者を使うか、お使いの NumPy のバージョンで対応していれば copy=True を渡して、その意図を明示してください。
次の例を実行します。コードと出力は原文どおり掲載しており、コード内の識別子などの表示は英語のままです。
import numpy as np
matrix = [[1, 2, 3], [4, 5, 6]]
array = np.asarray(matrix)
flat_copy = array.flatten()
flat_view_when_possible = array.ravel()
flat_reshape_when_possible = array.reshape(-1)
print(array.shape)
print(array)
print(flat_copy)
print(flat_view_when_possible)
print(flat_reshape_when_possible)
flat_copy[0] = 99
print(array[0, 0], flat_copy[0])
(2, 3)
[[1 2 3]
[4 5 6]]
[1 2 3 4 5 6]
[1 2 3 4 5 6]
[1 2 3 4 5 6]
1 99
最初の結果の形状は (2, 3) で、2次元のままです。後の結果の形状は (6,) で、1次元です。最後の代入で変更されるのは平坦化したコピーであり、array は変わりません。この例は正常に実行され、終了コードは0でした。
行列を1次元配列に平坦化する
array.flatten() は1次元のコピーを返すため、その結果の要素を変更しても元の配列は変わりません。後続のコードで平坦化したデータを変更する可能性があり、元の配列には影響させたくない場合に適した既定の選択肢です。
array.ravel() も1次元配列を作成します。ビューを作成できる場合はビューを返し、配列のメモリ配置上ビューを作れない場合はコピーを作成します。np.ravel(array) は対応する NumPy 関数であり、array.ravel() はそのメソッド形式です。データを共有できるかどうかはメモリ配置によって変わるため、ビューであると確認できていない限り、ravel() の結果への書き込みが元の配列にも反映されるとは考えないでください。
array.reshape(-1) メソッドは、要素数から1次元の形状を推定するよう NumPy に指示します。ビューを作成できればビューを返し、必要であればコピーを作成します。この操作で変わるのは結果の形状であり、この例で指定された要素の順序ではありません。3つの方法はいずれも既定ではC順序で平坦化します。異なる順序で走査する必要がある場合は、order 引数を指定してください。
平坦化の方法を選ぶ
独立したコピーを作り、変更が元の配列に影響しないことを確実にしたい場合は flatten() を選びます。簡潔に1次元の結果を得たい場合は ravel() を選びますが、元の配列のメモリ配置によって、メモリを共有する場合とコピーを作成する場合があります。形状変更として処理を表すのが周囲のコードに合う場合は reshape(-1) を選びます。この方法も、データを共有する場合とコピーを作成する場合があります。
変換と平坦化は、それぞれ異なる目的の操作です。2次元形状を保ったまま ndarray を得るには、np.asarray() または np.array() から始めます。次の関数が1次元の並びを必要とする場合にだけ、平坦化の操作を適用してください。元のデータを変更せずに残す必要があるなら、flatten() を使うか、変更する前に結果を明示的にコピーします。メモリ共有が性能や正しさに関わる場合は、どの ravel() や reshape も必ずビューになると思い込まず、配列同士の関係を確認してください。