Pythonでの数値計算 Numpy の使い方


*Numpy とは

Pythonの数値計算をするための拡張モジュールで、多次元配列や行列などを扱うことができる数学関数ライブラリを使うことができます。
Numpy を使うことで、高速に数値計算できる、配列の扱い方が楽になる、コードがシンプルになるといったメリットがあります。
使ったことがなかったので、基本的な動作を確認してみました。


*参考



*環境

  • MacOS
  • Python 2.7.14
  • Numpy 1.16.1


*インストール

仮想環境作成後、そのなかに入って下記コマンドを実行します。
$ pip install numpy

$ pip list
Package    Version
---------- -------
numpy      1.16.1 
pip        19.0.1 
setuptools 40.6.3 
wheel      0.32.3 

補足ですが、virtualenv でPython3系の仮想環境を作成してそのなかでnumpyを使おうとすると下記エラーが発生しました。
virtualenv のバグのようなので、取り急ぎ今回はPython2系の環境で動作確認をしています。
Original error was: PyCapsule_Import could not import module "datetime"


*演算

array()で配列を作成します。
作成した配列に対して演算をすると、全ての配列に対して演算をしてくれます。
# coding=utf-8  
import numpy as np  
  
# 配列を作成  
a = np.array([1, 2, 3])  
print(a)  
  
# 全ての配列の要素に対して演算(ブロードキャスト)  
print(a * 3)  
print(a + 2)

<結果>
[1 2 3]
[3 6 9]
[3 4 5]


*配列同士の演算

配列同士で演算をすると、同じインデックスに格納された値同士で演算をします。
# coding=utf-8  
import numpy as np  
  
# 配列を作成  
a = np.array([1, 2, 3])  
b = np.array([5, 5, 7])  

# 配列同士の演算(アダマール積)
print(a * b)

<結果>
[ 5 10 21]


*内積(積の和)

内積を求める場合はdot()を使います。
# coding=utf-8  
import numpy as np  
  
# 配列を作成  
a = np.array([1, 2, 3])  
b = np.array([5, 5, 7])  
  
# 内積
c = np.dot(a, b)  
print(c)

<結果>
36


*連続した配列の作成

連続した値の配列を作成する場合はarange()を使います。
# coding=utf-8  
import numpy as np  
  
# 連続した値の配列を作成  
a = np.arange(5, 20)  
# 連続した値の配列を3こずつに区切る  
b = np.arange(5, 20, 3)  
print(a)  
print(b)

<結果>
[ 5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
[ 5  8 11 14 17]


*配列の合計値

配列の和を求める場合はsum()を使います。
# coding=utf-8  
import numpy as np

# 和  
e = np.arange(0, 10)  
print(e)  
print(np.sum(e))

<結果>
[0 1 2 3 4 5 6 7 8 9]
45


*等分

指定した値の範囲内で等分にした配列を作成する場合はlinspace()を使います。
# coding=utf-8  
import numpy as np  
  
# 等分  
c = np.linspace(0, 20, 15)  
print(c)

<結果>
[ 0.          1.42857143  2.85714286  4.28571429  5.71428571  7.14285714
  8.57142857 10.         11.42857143 12.85714286 14.28571429 15.71428571
 17.14285714 18.57142857 20.        ]


*2次元配列の作成

array()で2次元配列を作成することもできます。
# coding=utf-8  
import numpy as np

# 2次元配列  
d = np.array([[1, 2, 3], [4, 5, 6]])  

# 値の取り出し
d_num = d[0, 1]

print(d)
print(d.shape)
print(d_num

<結果>
[[1 2 3]
 [4 5 6]]
 (2, 3)
 2


*多次元配列の演算

多次元配列と1次元の配列を演算すると、多次元配列の配列数に対して演算が行われます。(ブロードキャスティングといいます)
# coding=utf-8  
import numpy as np

g = np.array([1, 2, 3])  
h = np.array([[1, 2, 3],  
              [4, 5, 6]])  
# 配列の和              
sum1 = g + h  
print(sum1)

<結果>
[[2 4 6]
 [5 7 9]]


*配列構造の確認

多次元配列の構造を確認する場合はshapeを使うと、タプルで結果を返してくれます。何次元かを確認する場合はndimを使います。
その次元に対して、指定した次元だけで合計値などを求めたい場合はaxisで指定することができます。
# coding=utf-8  
import numpy as np

# 2次元配列の作成  
d = np.array([[1, 2, 3], [4, 5, 6]]) 
 
# 構造(A×B)  
d_shape = d.shape  

# 次元  
d_ndim = d.ndim  

# 座標軸(shapeのインデックスに対応) 行0, 列1  
d_sum1 = np.sum(d, axis=0)  
d_sum2 = np.sum(d, axis=1) 
 
print(d)  
print(d_shape)  
print(d_ndim)  
print(d_sum1)  
print(d_sum2)

<結果>
[[1 2 3]
 [4 5 6]]
(2, 3)
2
[5 7 9]
[ 6 15]


*配列構造の変更

多次元配列の要素数を変更する場合はreshape()を使います。
# coding=utf-8  
import numpy as np

# 構造を変更  
e = np.array([[1, 2, 3], [4, 5, 6]])  
e_list1 = e.reshape(3, 2)  
e_list2 = e.reshape(1, 6)  

print(e)  
print(e_list1)  
print(e_list2)

<結果>
[[1 2 3]
 [4 5 6]]
[[1 2]
 [3 4]
 [5 6]]
[[1 2 3 4 5 6]]


*乱数

乱数を作成する場合はrandom.randn()もしくはrandom.rand()を使います。
引数を指定して、作成した乱数を配列に格納することもできます。
# coding=utf-8  
import numpy as np

# 標準正規分布
rand_num1 = np.random.randn()  
# 0〜1
rand_num2 = np.random.rand() 
# 配列に格納
rand_num3 = np.random.randn(2, 3)
 
print(rand_num1)  
print(rand_num2)
print(rand_num3)

<結果>
-1.32052560845
0.894127851953


*スライス

標準の配列の扱いと同様、スライスを使うことができます。
# coding=utf-8  
import numpy as np

# スライス(始点:終点:間隔) 終点は含まれない  
f = np.array([0, 4, 3, 8, 1, 9])  
num1 = f[1:4]  
num2 = f[2:5:2]  

# 値を逆にする  
num3 = f[::-1]  

print(num1)  
print(num2)  
print(num3)

<結果>
[4 3 8]
[3 1]
[9 1 8 3 4 0]


*所感

多次元配列の扱いは苦手だったのですが、Numpyを使うことで簡単に計算ができたので大変便利でした。
使い方を覚えてしまえば高速に実装ができるので、データ分析など大量のデータを扱う際には必須になるかと思います。
他にも便利な関数があるようですので、理解を深めておこうと思います。

Previous
Next Post »

人気の投稿