プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/03/14

[Python] NumPy 入門

update2022/04/01 event_note2022/03/14 6:49

Python で高速に数値計算を行うためのライブラリである NumPy の基本的な使い方です。

環境

  • Python 3.8.10
  • numpy 1.22.2

インストールとインポート

$ pip install numpy

numpy をインポートする際、慣例的に np とすることが多いそうです。

import numpy as np

配列の作成

NumPy 配列は numpy.array で作成します。
戻り値の型は numpy.ndarray となります。

import numpy as np

# 一次元配列
arr1 = np.array([1,2,3])
print(type(arr1))
print(arr1)

# 二次元配列
arr2 = np.array([[1,2,3],[4,5,6]])
print(type(arr2))
print(arr2)
<class 'numpy.ndarray'>
[1 2 3]
<class 'numpy.ndarray'>
[[1 2 3]
 [4 5 6]]

空の配列を作成

import numpy as np

arr = np.empty(0)

print(arr)
print(type(arr))
[]
<class 'numpy.ndarray'>
import numpy as np

#(2,3)の形状の配列
arr = np.empty((2,3))

print(arr)
print(type(arr))
[[6.23042070e-307 1.33512376e-306 1.11261230e-306]
 [7.56577399e-307 9.34600963e-307 1.15860970e-311]]
<class 'numpy.ndarray'>

配列の自動生成

整数型

numpy.arange(開始値,終了値,間隔値) で整数型の配列を作成できます。

import numpy as np

arr = np.arange(21,31,1)
print(arr)
[21 22 23 24 25 26 27 28 29 30]

浮動小数型

numpy.linspace(開始値,終了値,要素数) で浮動小数型の配列を作成できます。

import numpy as np

arr = np.linspace(21,30,10)
print(arr)
[21. 22. 23. 24. 25. 26. 27. 28. 29. 30.]

値が全て0の配列

import numpy as np

arr = np.zeros(5)
print(arr)
[0. 0. 0. 0. 0.]

値が全て1の配列

import numpy as np

arr = np.ones(5)
print(arr)
[1. 1. 1. 1. 1.]

値が全て同じ任意の値の配列

import numpy as np

arr = np.full(5,2)
print(arr)
[2 2 2 2 2]

値が全て同じ任意の値の5x5の配列

import numpy as np

arr = np.full((5,5),2)
print(arr)
[[2 2 2 2 2]
 [2 2 2 2 2]
 [2 2 2 2 2]
 [2 2 2 2 2]
 [2 2 2 2 2]]

単位行列

import numpy as np

arr = np.eye(5)
print(arr)
[[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]

転置

以下のいずれかで転置できます。

  • numpy.transpose(配列)
  • 配列.transpose()
  • 配列.T

上記の3つは同じ挙動です。
また、shape で行列の形状を確認できます。

import numpy as np

# 2x3 の配列を生成
arr = np.random.randint(0,100,(2,3))
print(arr)
print(arr.shape)

# 配列の転置
arr = arr.T
print(arr)
print(arr.shape)
[[96 23 98]
 [62 95 13]]
(2, 3)
[[96 62]
 [23 95]
 [98 13]]
(3, 2)

転置方法を指定

import numpy as np

# 2x3x4 の配列を生成
arr = np.random.randint(0,100,(2,3,4))
print(arr)
print(arr.shape)

# 配列の転置
arr = arr.transpose((1,0,2))
print(arr)
print(arr.shape)
[[[90 75  5 21]
  [ 6  6 98 11]
  [16 75 99 46]]

 [[72 48 52  2]
  [ 2 75 49 29]
  [51 30 41 40]]]
(2, 3, 4)
[[[90 75  5 21]
  [72 48 52  2]]

 [[ 6  6 98 11]
  [ 2 75 49 29]]

 [[16 75 99 46]
  [51 30 41 40]]]
(3, 2, 4)

平坦化

flatten または ravel で配列を一次元化できます。 flatten は配列をコピーして平坦化されるそうですが、ravel は元の配列から変更されるようです。

import numpy as np

# 2x3x4 の配列を生成
arr = np.random.randint(0,100,(2,3,4))
print(arr)
print(arr.shape)

# 配列の平坦化
arr = arr.ravel()
print(arr)
print(arr.shape)
[[[17  6 76 10] 
  [83 33 17  4] 
  [ 5 91 62 26]]

 [[97 33 84  5]
  [ 9 62 95 12]
  [41 93 28 46]]]
(2, 3, 4)
[17  6 76 10 83 33 17  4  5 91 62 26 97 33 84  5  9 62 95 12 41 93 28 46]
(24,)

reshape と resize

reshaperesize はどちらも配列の形状を変更するための関数ですが、reshape は元の配列の要素数が変わるような変更はできないのに対し、resize は好きな形状に変更することができます。

resize で元の配列よりもサイズが小さい場合は値が切り捨てられ、大きい場合は複製されます。

import numpy as np

# 2x3の配列を生成
arr = np.random.randint(0, 100, (2,3))
print(arr)

# 2x3の配列を3x2の配列に変形する
print('reshape 2x3 -> 3x2')
arr1 = np.reshape(arr, (3,2))
print(arr1)

print('resize 2x3 -> 3x2')
arr2 = np.resize(arr, (3,2))
print(arr2)

# 2x3列の配列を2x2の配列に縮小する
print('resize 2x3 -> 2x2')
arr3 = np.resize(arr, (2,2))
print(arr3)

# 2x3列の配列を4x5の配列に拡大
print('resize 2x3 -> 4x5')
arr4 = np.resize(arr, (4,5))
print(arr4)
[[55 23  6]
 [24 44 17]]
reshape 2x3 -> 3x2
[[55 23]
 [ 6 24]
 [44 17]]
resize 2x3 -> 3x2
[[55 23]
 [ 6 24]
 [44 17]]
resize 2x3 -> 2x2
[[55 23]
 [ 6 24]]
resize 2x3 -> 4x5
[[55 23  6 24 44]
 [17 55 23  6 24]
 [44 17 55 23  6]
 [24 44 17 55 23]]

四則演算

配列同士で四則演算を行う方法として、関数を使用する方法と演算子を使用する方法があります。
ただし、乗算などは一般的な行列の積ではなく、同じ行と列の値同士の積となるようです。

import numpy as np
arr1 = np.array([100,200,300])
arr2 = np.array([40,50,60])

print(arr1 + arr2)
print(np.add(arr1, arr2))

# 減算
print(arr1 - arr2)
print(np.subtract(arr1, arr2))

# 乗算
print(arr1 * arr2)
print(np.multiply(arr1, arr2))

# 除算
print(arr1 / arr2)
print(np.divide(arr1, arr2))
[140 250 360]
[140 250 360]
[ 60 150 240]
[ 60 150 240]
[ 4000 10000 18000]
[ 4000 10000 18000]
[2.5 4.  5. ]
[2.5 4.  5. ]