ホーム テクノロジー 開発 NumPy 配列: 概要 [例付き]

NumPy 配列: 概要 [例付き]


NumPy を始めてみませんか?このガイドでは、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

: NumPy をエイリアスnpでインポートすることは必須ではありませんが、推奨される規則です。

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()関数を呼び出します。これが、NumPy の基本データ構造であるndarrayであることがわかります。

 type(np_arr1)
# numpy.ndarray

Python リストと NumPy 配列は似ているように見えますが、いくつかの違いがあります。

  • Python リストは異なるデータ型のオブジェクトを保持できますが、NumPy 配列には同じデータ型の要素が含まれます。デフォルトのデータ型は、精度が 64 ビット (float64) の float です。
  • Python リストの要素は、必ずしもメモリ内の連続した場所に格納されるとは限りません。ただし、NumPy 配列の要素はメモリ内の連続したブロックに格納されます。その結果、要素の検索とアクセスがより速くなります。

他のいくつかの違いを見てみましょう。

放送

NumPy 配列の強力な機能はブロードキャストです。 np_arr1py_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) です。このセクションでは、これらの組み込み関数のいくつかの使用方法を学びます。

NumPy 配列の作成方法
NumPy 配列の作成方法

0 と 1 の配列の作成

多くの場合、すべて 0 またはすべて 1 が入力された特定の次元の配列を作成すると便利です。そして、それらを使用し、プログラムの後続のステップで変更します。

zeros()関数を使用してゼロの配列を作成できます。必要な配列の形状をタプルとして渡します: np.zeros(shape)

 array0 = np.zeros((3,3))
print(array0)

出力はゼロの 2D 配列です。

 [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

以下に示すように、ドット表記を使用して、NumPy 配列の属性にアクセスし、 dtypeshapeなどの属性を呼び出すことができます。

 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 のランダム モジュールの一部である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()関数は、 startstop値の間の数値の配列をstep値ごとに返します: startstart + stepstart + 2*step up to ( stopは含まれません)。 startstep値はオプションです。デフォルトのステップ サイズは 1 で、デフォルトの開始値は 0 です。

この例では、 array_a 1 から始まり、10 を含まない 0.5 刻みの数値の配列です。

 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)を使用して、 startstop値の間に等間隔に配置された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()関数にはデフォルトでエンドポイントが含まれています

NumPy 配列の基本操作

次に、NumPy 配列の基本的な操作をいくつか見てみましょう。

最小要素と最大要素を見つける

NumPy のランダム モジュールの関数を使用して配列を作成すると、コードを実行するたびに異なる結果が得られます。再現可能な結果を​​得るには、シードを設定する必要があります: 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_arr1min()メソッドを呼び出します。
 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)を使用して、それぞれ最大要素と最小要素のインデックスを見つけることもできます。 NumPy argmax()関数について詳しく学習してください。

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))

スタックは水平方向に行われるため、入力配列の行数同じである必要があります。ここでは、 arr1arr2両方に 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()関数と同様に、連結軸に沿った配列の次元は一致する必要があります

結論

このチュートリアルでは、速度と効率の点での N 次元配列の利点に焦点を当てながら、NumPy 配列と Python リストの違いを学習しました。

また、特定の次元の配列を作成し、最小要素と最大要素の検索、配列の連結などの一般的な操作を実行するためのいくつかの便利な関数も学習しました。

次に、NumPy 配列を再構成する方法を学びます。

「 NumPy 配列: 概要 [例付き]」についてわかりやすく解説!絶対に観るべきベスト2動画

【Pythonプログラミング】NumPyの基本 〜 Pythonで科学計算や機械学習を扱う人必見!〜
【毎日Python】Pythonで等間隔の配列を作成する方法|numpy.linspace