NumPy reshape(): Python で NumPy 配列を再形成する方法

NumPy reshape(): Python で NumPy 配列を再形成する方法

このチュートリアルでは、 NumPy reshape()を使用して、元のデータを変更せずに NumPy 配列を再形成する方法を学びます。

Numpy 配列を使用する場合、既存の配列を異なる次元の配列に再形成したい場合があります。これは、データを複数の手順で変換する場合に特に便利です。

NumPy reshape()使用すると、それを簡単に行うことができます。次の数分間で、 reshape()を使用する構文と、配列を異なる次元に再形成する構文を学習します。

NumPy 配列の再形成とは何ですか?

NumPy 配列を使用する場合、最初に数値の 1 次元配列を作成したい場合があります。次に、それを目的の次元の配列に再形成します。

これは、新しい配列の次元が最初に不明な場合、または実行中に推測される場合に特に役立ちます。あるいは、特定のデータ処理ステップで特定の形状の入力が必要になる可能性もあります。

ここでリシェイプが役に立ちます。

たとえば、次の図を考えてみましょう。 6 つの要素からなる 1 次元配列であるベクトルがあります。そして、それを 2×3、3×2、6×1 などの形状の配列に再形成することができます。

numpy-reshape
numpy-reshape

▶️ このチュートリアルの例に従うには、Python と NumPy がインストールされている必要があります。 NumPy をまだお持ちでない場合は、NumPy インストール ガイドをご覧ください。

import numpy as npを実行して、エイリアスnpの下で NumPy をインポートします。

次のセクションで構文の学習に進みましょう。

NumPy reshape() の構文

NumPy reshape() を使用する構文は次のとおりです。

 np.reshape(arr, newshape, order = 'C'|'F'|'A')
  • arr は、任意の有効な NumPy 配列オブジェクトです。ここでは、再形成される配列です。
  • newshapeは、新しい配列の形状です。整数またはタプルのいずれかを指定できます。
  • newshapeが整数の場合、返される配列は 1 次元になります。
  • order は、再形成する配列の要素を読み取る順序を指します。
  • デフォルト値は「C」です。これは、元の配列の要素が C のようなインデックス順 (0 から始まる) で読み取られることを意味します。
  • 「F」は、 Fortran のようなインデックス作成 (1 から始まる) を表します。そして、 「A」は、配列arrのメモリ レイアウトに応じて、C のような順序または Fortran のような順序で要素を読み取ります。

では、 np.reshape()何を返しますか?

可能であれば、元の配列の再形成されたビューを返します。それ以外の場合は、配列のコピーを返します。

上の行で、NumPy reshape()可能な限りビューを返そうとすると述べました。それ以外の場合は、コピーを返します。ビューとコピーの違いについて説明していきましょう。

NumPy 配列の表示とコピー

名前が示すように、コピーは元の配列のコピーです。また、コピーに加えられた変更は元の配列には影響しません

一方、ビューは単に元の配列の再形成されたビューを指します。これは、ビューに加えられた変更は元の配列にも影響し、その逆も同様であることを意味します。

NumPy reshape() を使用して 1D 配列を 2D 配列に変形する

#1. np.arange()を使用してサンプル配列を作成することから始めましょう。

arr1 という 1 から 12 までの 12 個の数値の配列が必要です。 NumPy arange() 関数はデフォルトでエンドポイントを除外するため、ストップ値を 13 に設定します。

次に、上記の構文を使用して、12 個の要素を含むarr1を形状 (4,3) の 2D 配列に再形成してみましょう。これを 4 行 3 列のarr2と呼びます。

 import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr2 = np.reshape(arr1,(4,3))
print("\nReshaped array:")
print(arr2)

元の配列と再形成された配列を見てみましょう。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

配列を引数np.reshape()として渡す代わりに、元の配列で.reshape()メソッドを呼び出すこともできます。

dir(arr1)を実行すると、配列オブジェクトarr1で使用できるすべてのメソッドと属性がリストされます。

 dir(arr1)

# Output 
[
...
...
'reshape'
...
..
]

上記のコードセルでは、 .reshape()既存の NumPy 配列arr1で使用する有効なメソッドであることがわかります。

▶️ したがって、次の簡略化された構文を使用して NumPy 配列を再構成することもできます。

 arr.reshape(d0,d1,...,dn)

# where:

# d0, d1,..,dn are the dimensions of the reshaped array

# d0 * d1 * ...* dn = N, the number of elements in arr

このチュートリアルの残りの部分では、例でこの構文を使用してみましょう。

#2. 12 要素ベクトルを 12 x 1 配列に再形成してみましょう。

 import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr3 = arr1.reshape(12,1)
print("\nReshaped array:")
print(arr3)

以下の出力では、配列が必要に応じて再形成されたことがわかります。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1]
 [ 2]
 [ 3]
 [ 4]
 [ 5]
 [ 6]
 [ 7]
 [ 8]
 [ 9]
 [10]
 [11]
 [12]]

❔ では、コピーまたはビューを取得したかどうかを確認するにはどうすればよいでしょうか?

これを確認するには、返された配列のbase属性を呼び出します。

  • 配列がコピーの場合、 base属性はNoneになります。
  • 配列がビューの場合、 base属性は元の配列になります。

早速検証してみましょう。

 arr3.base
# Output
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

ご覧のとおり、 arr3base属性は元の配列を返します。これは、元の配列のビューを受け取ったことを意味します。

#3.ここで、ベクトルを別の有効な 2 x 6 配列に再形成してみましょう。

 import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr4 = arr1.reshape(2,6)
print("\nReshaped array:")
print(arr4)

そして出力は次のとおりです。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[ 1  2  3  4  5  6]
 [ 7  8  9 10 11 12]]

次のセクションでは、 arr1 3D 配列に再形成しましょう。

NumPy reshape() を使用して 1D 配列を 3D 配列に変形する

arr1 3D 配列に再形成するには、目的の次元を (1, 4, 3) に設定しましょう。

 import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr3D = arr1.reshape(1,4,3)
print("\nReshaped array:")
print(arr3D)

これで、元の配列arr1と同じ 12 個の要素を持つ 3D 配列が作成されました。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]

Reshaped array:
[[[ 1  2  3]
  [ 4  5  6]
  [ 7  8  9]
  [10 11 12]]]

再形成中の値エラーをデバッグする方法

構文を覚えておくと、再形成は次元の積が配列内の要素の数と等しい場合にのみ有効です。

 import numpy as np

arr1 = np.arange(1,13)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr2D = arr1.reshape(4,4)
print("\nReshaped array:")
print(arr2D)

ここでは、12 要素の配列を 16 要素の 4×4 配列に再形成しようとしています。以下に示すように、インタープリタは値エラーをスローします。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12]
-----------------------------------------------------------
ValueError                                
Traceback (most recent call last)
<ipython-input-11-63552bcc8c37> in <module>()
      6 
      7 # Reshape array
----> 8 arr2 = arr1.reshape(4,4)
      9 print("\nReshaped array:")
     10 print(arr2)

ValueError: cannot reshape array of size 12 into shape (4,4)

このようなエラーを回避するには、 -1を使用して、要素の合計数に基づいて、いずれかの次元の形状を自動的に推測します。

たとえば、n – 1 次元が事前にわかっている場合は、-1 を使用して、再形成された配列の n 番目の次元を推測できます。

24 要素の配列があり、それを 3D 配列に再形成したい場合。 3 行 4 列が必要だとします。 3 番目の次元に沿って値 -1 を渡すことができます。

 import numpy as np

arr1 = np.arange(1,25)
print("Original array, before reshaping:\n")
print(arr1)

# Reshape array
arr_res = arr1.reshape(4,3,-1)
print("\nReshaped array:")
print(arr_res)
print(f"Shape of arr_res:{arr_res.shape}")

形状配列の形状を調べると、再形成された配列の 3 次元方向の形状が 2 であることがわかります。

 Original array, before reshaping:

[ 1  2  3  4  5  6  7  8  9 10 11 12 
13 14 15 16 17 18 19 20 21 22 23 24]

Reshaped array:
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]

 [[13 14]
  [15 16]
  [17 18]]

 [[19 20]
  [21 22]
  [23 24]]]
Shape of arr_res:(4, 3, 2)

これは、配列をフラット化する場合に特に役立ちます。それについては次のセクションで学びます。

NumPy reshape() を使用して配列を平坦化する

N 次元配列からフラット化された配列に戻す必要がある場合があります。画像をピクセルの長いベクトルに平坦化するとします。

次の手順を使用して簡単な例をコーディングしてみましょう。

  • 0 ~ 255 の範囲のピクセルを含む 3 x 3 のグレースケール イメージ配列img_arrを生成します。
  • 次に、このimg_arrフラット化し、フラット化された配列flat_arr出力します。
  • また、 img_arrflat_arrの形状を出力して確認します。
 img_arr = np.random.randint(0, 255, (3,3))
print(img_arr)
print(f"Shape of img_arr: {img_arr.shape}")
flat_arr = img_arr.reshape(-1)
print(flat_arr)
print(f"Shape of flat_arr: {flat_arr.shape}")

これが出力です。

 [[195 145  77]
 [ 63 193 223]
 [215  43  36]]
Shape of img_arr: (3, 3)

[195 145  77  63 193 223 215  43  36]
Shape of flat_arr: (9,)

上記のコード セルでは、 flat_arr 9 つの要素を持つピクセル値の 1D ベクトルであることがわかります。

まとめ👩‍🏫

学んだことを簡単に復習しましょう。

  • np.reshape(arr, newshape)を使用して、 arr をnewshapeで指定された形状に再形成します。 newshapeは、再形成された配列の次元を指定するタプルです。
  • あるいは、 arr.reshape(d0, d1, …, dn) を使用してarr をd0 x d1 x … x dnの形状に再形成します。
  • 再形成中の値エラーを避けるために、元の配列の要素の数d0 * d1 * …* dn = Nかどうかを確認します。
  • 寸法を自動的に推測したい場合は、新しい形状の最大 1 つの寸法に-1を使用します。
  • 最後に、 arr.reshape(-1)を使用して配列を平坦化することができます。

NumPy reshape() の使用方法がわかったので、NumPy linspace() 関数がどのように機能するかを学びましょう。

必要に応じて、Jupyter ノートブックのコード例を試してみることもできます。他の開発環境をお探しの場合は、Jupyter の代替案に関するガイドをご覧ください。

「 NumPy reshape(): Python で NumPy 配列を再形成する方法」についてわかりやすく解説!絶対に観るべきベスト2動画

【毎日Python】Pythonで配列を作成する方法|numpy.arange
【こつこつPython】Pythonで配列を繰り返す方法|numpy.repeat