NumPy 配列: 概要 [例付き]
公開: 2022-12-08NumPy を始めてみませんか? このガイドでは、Python での NumPy 配列の基本について説明します。
最初のステップとして、NumPy 配列が Python のリストとどのように異なるかを学びます。 次に、NumPy 配列を作成し、それらに対して基本的な操作を実行するいくつかの方法を学習します。
さぁ、始めよう!
NumPy 配列の基礎
NumPy は、科学計算とデータ分析のための最も人気のある Python ライブラリの 1 つです。 NumPy の基本的なデータ構造は N 次元配列 (ND 配列) です。 それらにはブロードキャスト機能があり、速度を上げるために操作をベクトル化し、組み込みの数学関数を使用してパフォーマンスを向上させることができます。
NumPy の使用を開始するには、まずライブラリをインストールして作業環境にインポートする必要があります。 これは、pip を介してインストール可能な PyPI パッケージとして入手できます。
NumPy をインストールするには、ターミナルを開いて次のコマンドを実行します。
pip3 install numpy
NumPy をインストールしたら、エイリアスを使用して作業環境にインポートできます。 通常のエイリアスはnp
です。
import numpy as np
注: エイリアス
np
の下で NumPy をインポートすることは必須ではありませんが、推奨される規則です。
Python リストと NumPy 配列
次の Python の数値リストを考えてみましょう。
py_list = [1,2,3,4]
リストを引数としてnp.array()
関数を呼び出すことで、既存のリストから NumPy 配列を取得できます。
np_arr1 = np.array(py_list) print(np_arr1) [1 2 3 4]
np_arr1
の型を確認するには、組み込みのtype()
関数を呼び出しますndarray
の基本的なデータ構造である ndarray であることがわかります。
type(np_arr1) # numpy.ndarray
Python リストと NumPy 配列は似ているように見えますが、いくつかの違いがあります。
- Python リストは異なるデータ型のオブジェクトを保持できますが、NumPy 配列には同じデータ型の要素が含まれます。 デフォルトのデータ型は float で、精度は 64 ビットです (float64)。
- Python リストの要素は、メモリ内の連続した場所に格納されるとは限りません。 ただし、NumPy 配列の要素はメモリ内の連続したブロックに格納されます。 その結果、要素の検索とアクセスが高速になります。
他のいくつかの違いについて見ていきましょう。
放送
NumPy 配列の強力な機能はブロードキャストです。 np_arr1
とpy_list
のすべての要素に 2 を追加したいとします。
py_list
に 2 を追加して、何が起こるか見てみましょう:
>>> py_list + 2
連結できるのは 2 つのリストのみであり、このように py_list + 2 を追加することはサポートされていないことを示す TypeError が返されることがわかります。
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-5-c0f9974899df> in <module> ----> 1 py_list + 2 TypeError: can only concatenate list (not "int") to list
配列np_arr1
で同じ操作を試してみましょう。
>>> np_arr1 + 2
結果では、配列の各要素に 2 が追加されていることがわかります。
array([3, 4, 5, 6])
これは、NumPy がスカラー 2 を互換性のある形状の配列に暗黙的にブロードキャストして、この結果を生成したためです。
ベクトル化
NumPy 配列は、要素単位の操作を高速化するためのベクトル化をサポートしています。 2 つの配列の要素ごとの合計を求めたいとします。
リストに対して単純な+
操作を使用すると、2 つのリストの連結が返されます (これは、私たちが望んでいるものではありません!)。
>>> py_list + py_list # [1, 2, 3, 4, 1, 2, 3, 4]
しかし、NumPy 配列np_arr1
に対する同じ操作は、 np_arr1
とそれ自体の要素ごとの合計を返します。
>>> np_arr1 + np_arr1 # array([2, 4, 6, 8])
同様に、ネストされたリストは、N 次元の NumPy 配列と構造が似ている場合があります。 ただし、これまでに説明した違いは保持されます。
nested_list = [[1,2],[3,4],[5,6]] np_arr2 = np.array(nested_list) print(np_arr2)
[[1 2] [3 4] [5 6]]
NumPy 配列の作成方法
np.array(list-obj)
を使用して、既存の Python リストからいつでも NumPy 配列を作成できます。 ただし、これは最も効率的な方法ではありません。
代わりに、特定の形状の配列を作成できるいくつかの組み込み関数を使用できます。 配列の形状は、各次元に沿った配列のサイズを示すタプルです。 たとえば、2 行 2 列の 2×2 配列の形状は (2,2) です。 このセクションでは、これらの組み込み関数の使用方法を学習します。
0 と 1 の配列の作成
すべてゼロまたはすべて 1 で設定された特定の次元の配列を作成すると役立つことがよくあります。 そして、それらを使用して、プログラムの後続のステップで変更します。
zeros()
関数を使用してゼロの配列を作成できます。 必要な配列の形状をタプルとして渡します: np.zeros(shape)
。
array0 = np.zeros((3,3)) print(array0)
ゼロの 2D 配列である出力は次のとおりです。
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
以下に示すように、ドット表記を使用して、NumPy 配列の属性にアクセスし、 dtype
やshape
などの属性を呼び出すことができます。
print(array0.dtype) # float64 print(array0.shape) # (3, 3)
1 の配列を取得するには、 np.ones()
関数を使用できます。
array1 = np.ones((3,3)) print(array1)
[[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]]
恒等マトリックスの作成
単位行列は、線形代数のいくつかのアプリケーションで広く使用されています。 また、 np.eye()
関数を使用して恒等行列を作成できます。 np.eye()
関数は、行列の順序 ( n
) という 1 つの引数のみを受け取ります。
arrayi = np.eye(3) print(arrayi)
[[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]]
乱数の配列の作成
特定の分布から引き出された乱数が取り込まれた特定の形状の配列を作成することもできます。 一般的に使用される確率分布は、一様分布と標準正規分布です。
NumPy のrandom
モジュールの一部であるrandn()
関数を使用して、標準の正規分布からサンプリングされた数値の配列を生成できます。 標準正規分布は、平均がゼロで分散が単位のガウス分布です。
std_arr = np.random.randn(3,4) print(std_arr)
[[-0.13604072 1.21884359 2.06850932 0.78212093] [ 0.44314719 -0.78084801 -0.70517138 1.17984949] [ 1.13214829 1.02339351 0.15317809 1.83191128]]
np.random.rand()
は、間隔 [0,1) にわたる一様分布からの数値サンプルの配列を返します。
uniform_arr = np.random.rand(2,3) print(uniform_arr)
[[0.90470384 0.18877441 0.10021817] [0.741 0.10657658 0.71334643]]
NumPy の random モジュールの一部であるrandint()
関数を使用して、ランダムな整数の配列を作成することもできます。 np.random.randint(low, high, size)
は整数の配列を返します。 配列の形状はsize
引数から推測され、整数は区間[low,high)
の値を取ります。
次に例を示します。
int_arr = np.random.randint(1,100,(2,3)) print(int_arr)
[[53 89 33] [24 85 33]]
その他の便利な組み込み関数
次に、NumPy 配列を作成するためのその他の便利な関数について説明します。
arange()
関数は、 step
値のステップでstart
値とstop
値の間の数値の配列を返します: start
、 start + step
、 start + 2*step
まで、 stop
は含みません。 start
値とstep
値はオプションです。 デフォルトのステップ サイズは 1 で、デフォルトの開始値は 0 です。
この例では、 array_a
は 1 から始まり、0.5 刻みで 10 を含まない 10 までの数値の配列です。
array_a = np.arange(1,10,0.5) print(array_a)
[1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5 8. 8.5 9. 9.5]
np.linspace()
を使用して、等間隔の数値の配列を作成することもできます。 np.linspace(start, stop, num)
stop
使用して、 start
値と終了値の間の等間隔の数値num
の配列を取得します。
ここで、 arr_lin
は [1,10] の間隔で等間隔に配置された 5 つの数値の配列です。
array_lin = np.linspace(1,10,5) print(array_lin)
[ 1. 3.25 5.5 7.75 10. ]
同様に、 arr_lin2
は、[1,20] の間隔で等間隔に配置された 10 個の数値の配列です。
array_lin2 = np.linspace(1,20,10) print(array_lin2)
[ 1. 3.11111111 5.22222222 7.33333333 9.44444444 11.55555556 13.66666667 15.77777778 17.88888889 20. ]
arange() 関数とは異なり、 linspace()
arange()
にはデフォルトでエンドポイントが含まれます。
NumPy 配列の基本操作
次に、NumPy 配列の基本的な操作について説明します。
最小要素と最大要素を見つける
NumPy の random モジュールの関数を使用して配列を作成すると、コードが実行されるたびに異なる結果が得られます。 再現可能な結果を得るには、シードを設定する必要があります: np.random.seed(seed_value)
。
次の例では、再現性のためにシードを設定していますint_arr1
は、間隔 [1,100) 内の 7 つのランダムな整数の配列です。
np.random.seed(27) int_arr1 = np.random.randint(1,100,7) print(int_arr1) # [20 57 73 32 57 38 25]
- 配列内の最大要素を見つけるには、配列オブジェクト
int_arr1
でmax()
メソッドを呼び出します。 - 配列内の最小要素を見つけるには、配列オブジェクト
int_arr1
でmin()
メソッドを呼び出します。
int_arr1.max() # 73 int_arr1.min() # 20
最大要素と最小要素のインデックスを見つける
場合によっては、最大要素と最小要素のインデックスを見つける必要がある場合があります。 これを行うには、配列オブジェクトでargmax()
およびargmin()
メソッドを呼び出すことができます。
ここでは、最大要素 73 がインデックス 2 で発生します。
int_arr1.argmax() # 2
また、最小要素 20 はインデックス 0 にあります。
int_arr1.argmin() # 0
np.argmax(array)
とnp.argmin(array)
を使用して、それぞれ最大要素と最小要素のインデックスを見つけることもできます。 NumPyargmax()
関数の詳細をご覧ください。
NumPy 配列を連結する方法
NumPy 配列で行うことができるもう 1 つの一般的な操作は、連結です。
vstack を使用した垂直連結
vstack()
関数を使用して、配列を垂直方向に連結できます。
ここに例があります。 arr1
は 2 行 3 列の 1 の配列で、 arr2
は 2 行 3 列の 0 の配列です。
arr1 = np.ones((2,3)) arr2 = np.zeros((2,3))
次のようにvstack()
関数を使用して、これら 2 つの配列を垂直方向に連結できます。
np.vstack((arr1,arr2))
array([[1., 1., 1.], [1., 1., 1.], [0., 0., 0.], [0., 0., 0.]])
スタッキングは垂直方向に行われるため、2 つの配列の列数は同じである必要があります。
arr2
を (2,2) の形に変更しましょう。 これで、2 行 2 列になりました。
arr1 = np.ones((2,3)) arr2 = np.zeros((2,2)) np.vstack((arr1,arr2))
したがって、垂直方向の連結は不可能で、ValueError が返されます。
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-21-d5d3bf37fc21> in <module> ----> 1 np.vstack((arr1,arr2)) ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 3 and the array at index 1 has size 2
hstack を使用した水平連結
以下に示すように、 hstack()
関数を使用して、NumPy 配列を水平方向に連結できます。
arr1 = np.ones((3,3)) arr2 = np.zeros((3,2))
np.hstack((arr1,arr2))
積み重ねは水平方向に行われるため、入力配列は同じ数の行を持つ必要があります。 ここでは、 arr1
とarr2
の両方に 3 つの行があります。
array([[1., 1., 1., 0., 0.], [1., 1., 1., 0., 0.], [1., 1., 1., 0., 0.]])
連結の使用
concatenate()
関数を使用して、特定の軸に沿って連結 NumPy 配列を使用することもできます。 オプションのaxis
引数を、連結したい軸に設定します。 軸のデフォルト値はゼロです。
以下にいくつかの例を示します。
arr1 = np.ones((2,3)) arr2 = np.zeros((2,3))
連結する軸を指定しない場合、配列は軸 0 に沿って連結されます。結果の配列では、2 番目の配列arr2
が最初の配列の下に (行として) 追加されます。
np.concatenate((arr1,arr2))
array([[1., 1., 1.], [1., 1., 1.], [0., 0., 0.], [0., 0., 0.]])
axis = 1
を指定すると、次の結果が得られます。 arr2
は、最初の配列arr1
の横に (列として) 連結されます。
np.concatenate((arr1,arr2),axis=1)
array([[1., 1., 1., 0., 0., 0.], [1., 1., 1., 0., 0., 0.]])
hstack()
およびvstack()
関数と同様に、連結軸に沿った配列の次元は一致する必要があります。
結論
このチュートリアルでは、NumPy 配列と Python リストの違いを学び、速度と効率に関する N 次元配列の利点に焦点を当てました。
また、特定の次元の配列を作成し、最小要素と最大要素の検索、配列の連結などの一般的な操作を実行するためのいくつかの便利な関数についても学習しました。
次に、NumPy 配列を再形成する方法を学びます。