福岡は今日も雨

情報系大学生のブログ。主に技術,音楽について。

numpyについて

numpyとは,配列の処理に特化したライブラリで, Pythonのそれよりも高速に処理することができる.
行列演算を簡単に, 高速に行うことができるものであり, 以下の3つの機能を提供している.

(1)ユニバーサル関数
(2)各種関数群
(3)C/C++など, 他言語へのインターフェース

numpyが高速な理由の一つに, RAMのメモリに配列のデータがびっしりと敷き詰められるから, というのがある.
こういう形にすることで, オーバヘッドを抑えることが可能になる.

numpyの組み込みデータ型

組み込みデータ型はたくさんある. 数値を扱うものが大半だが,pythonのオブジェクトを格納するものもある.
これらを使って以下のように書く.

import numpy as np

# 組み込みデータ型(配列)の形で生成する
a = np.complex128([3.2, 4.2+1.09j])

# np.array()で生成し, dtypeに属性を付加することもできる
b = np.array([2234.432, 2.23], dtype=np.single)

多次元配列オブジェクトndarrayについて

Pythonのオブジェクトには, 配列と行列があり, これらを区別して使用しなければならない
たとえば, S = (HVH^T)^-1という行列を計算するとき,以下のような書き方ができる.

# 行列を利用する
import numpy as np

H = np.matrix([[1, 2], [3, 4]])

V = np.matrix([[3, 4], [5, 6]])

S = inv(H * V * H.T)

行列を使えば直感的にかけるが, 配列とごっちゃになる可能性があるので, あまり使用しない.
Python3.5~からは, 配列でも同様に演算できるように @演算子が追加された

import numpy as np

H = np.array([[1, 2], [3, 4]])

V = np.array([[3, 4], [5, 6]])

#従来
S = inv(H.dot(V.dot(H.T)))

#python3.5~
S = inv(H @ V @ H.T)

行列は原則使用しないようにする

ndarrayの生成

pythonのリストやタプルは, そのままnp.array(..)にいれることで, ndarrayオブジェクトに変換できる.
しかし, pythonの配列と違い, いくつか注意点がある

(1) 基本的に同じ型になる
(2) 各次元の要素数が同じ

import numpy as np

mat = [[3, 1, 9], [2, 5, 8], [4, 7, 6]]

array1 = np.array(mat)

その他, arrayだけでなく, arange, one, zerosなどがある.
ones, zerosは1のみ, 0のみの行列を生成する. np.zeros(行, 列)で指定する
arangeはrangeと同じで, (start, end, step)で指定する.

import numpy as np

a = np.zeros(2, 3)

b = np.arange(10, 20, 2)

np.arange(..)は浮動小数点も可能だが, そのときendの値が入ってしまうことには注意しておく.

データ型の指定

(1) Generic Typeによる指定
(2) Pythonの組み込みデータ型に対応する型指定
(3) numpyの組み込みデータ型による指定
(4) 文字コードによる指定

がある. 個人的には(3)が一番使われているような気がする

import numpy as np

dt = np.dtype('float')

# データ型のdtypeオブジェクトを引数に
x = np.array([1.1, 2.1, 3.1], dtype=dt)

# 文字で指定することも可能
x = np.array([1.1, 2.1, 3.1], dtype='float')

numpyの属性

numpyには行列演算のメソッドとは別に, ndarrayの状態を取得する属性群がある.
その中でも, 今回はshapeとndimに焦点を当てる(最初ndimがわからなかった)

import numpy as np

mat = [[3, 1, 9], [2, 5, 8], [4, 7, 6]]

array1 = np.array(mat)

array1.shape
# => (3, 3)

array1.ndim
# => 2

shapeは行*列でタプルで返す関数である.
ndimは, 行列の次元数であり, ベクトルなら1, 行列ならば2, 3次元のテンソルなら3..となっていく.

ndarrayの行列演算

行列演算について, ndarrayの+, -, *, / などの演算は要素同士の演算になることに注意をする.
もし, 行列積を出したいときは, dotか@演算子を使って演算すること.
逆行列演算や, 行列式計算, ランク計算はnumpyで簡単に計算できる

In [32]: np.linalg.inv(mat)
Out[32]:
array([[ 0.23214286, -0.50892857,  0.33035714],
       [-0.17857143,  0.16071429,  0.05357143],
       [ 0.05357143,  0.15178571, -0.11607143]])

In [33]: np.linalg.det(mat)
Out[33]: -112.00000000000006

In [34]: np.linalg.matrix_rank(mat)
Out[34]: 3

インデキシング以降を明日に見ていく.