HOWTO · NumPy
Python で 3D 配列を 2D 配列に変換する
NumPy パッケージの reshape()関数を使用して、Python で 3D 配列を 2D 配列に変換できます。
このページの内容
NumPyのnumpy.reshape()を使うと、値を保ったまま3D配列を2D配列に変換できます。入力と要素数が同じになるよう、各次元の積が等しい2Dの形状を指定します。形状が(4, 2, 2)の配列を(4, 4)に変換すると、先頭軸ごとの要素がそれぞれ1行に並び、残り2つの軸が列方向にまとめられます。適切なまとめ方は、データをどのように解釈するかによって異なります。
3D配列の形状を理解する
3DのNumPy配列には3つの軸があり、arr.shapeは各軸の長さをタプルで返します。軸が必ず奥行き、高さ、幅を表すわけではなく、その意味はデータによって決まります。たとえば、画像の配列では高さ、幅、色チャンネルが各軸に対応することがあり、シミュレーションでは時間、行、列が対応することがあります。形状を変更する前に、どの次元を行にし、どの次元を列にまとめるかを決めましょう。reshapeで変わるのは軸の構成であり、値そのものではありません。
NumPyのreshape()で3D配列を変換する
行数と列数を含むタプルをreshape()に渡します。この例では、0から15までの値を作って(4, 2, 2)の配列にし、末尾の2軸を組み合わせて4列にまとめます。
次の例を実行します。
このセクションのコードと表示されるラベルや出力は英語のままです。
import numpy as np
arr = np.arange(16).reshape(4, 2, 2)
arr_2d = arr.reshape(4, 4)
print("Input shape:", arr.shape)
print("Output shape:", arr_2d.shape)
print(arr_2d)
Input shape: (4, 2, 2)
Output shape: (4, 4)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
出力先の形状(4, 4)は、4行4列を表します。NumPyは指定されたインデックス順に値を保持するため、新しい各行には選択した軸の構成に従って元の値がまとめられます。別のまとめ方が必要なら、出力先の形状を変更してください。あらゆる3Dデータに当てはまる唯一の2D配置があるわけではありません。
入力配列から2Dの形状を導く
入力の次元が一定でない場合は、値を直接書き込まずarr.shapeから取得します。入力形状が(a, b, c)で、先頭軸の各スライスを1行にするなら、出力形状は(a, b * c)です。コードではrows, height, width = arr.shapeとして、arr.reshape(rows, height * width)を使います。これにより先頭軸はそのまま保たれ、2番目と3番目の軸がまとめられます。行にしたいデータが別の軸に対応する場合は、軸を並べ替えるか転置してから、意図した構成に合う出力形状を選びます。
次元の1つを-1で指定し、NumPyに推定させることもできます。たとえばarr.reshape(arr.shape[0], -1)と書きます。NumPyは要素数と、ほかに指定された次元からその値を計算します。出力形状が曖昧にならないよう、推定する次元は1つだけにしてください。
要素の順序:C順とFortran順
既定では、reshape()はC形式のインデックス順を使います。これは、入力から値を読み取り、結果に配置するときに、最後の軸が最も速く変化する順序です。order='F'を渡すとFortran形式のインデックス順になり、最初の軸が最も速く変化します。order引数が指定するのはreshape時に使うインデックス順であり、物理メモリ上の配置を保証するものではありません。ほとんどの変換では既定値で問題ありません。結果の値の並びをFortran形式にしたい場合にのみ、Fortran順を選んでください。
形状の互換性とよくあるエラー
入力と出力の各次元の積は等しくなければなりません。(4, 2, 2)の入力には16個の要素があるため、(4, 4)や(2, 8)なら同じ値を収められますが、(4, 5)には収まりません。指定した形状の要素数が合わないと、NumPyはValueErrorを発生させます。このエラーの原因を調べるには、arr.sizeを確認するか、各次元の積を計算してください。また、選択した行と列のまとめ方がデータの意味に合っているかも確認しましょう。数学的に互換性のある形状でも、次の処理に適さない値の並びになることがあります。
関数のパラメーターと動作については、公式のNumPy reshape APIリファレンスを参照してください。