「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
多次元配列における数値計算を効率的に行うことをサポートする数学関数ライブラリ
- 効率的な数値計算を行うための型付きの多次元配列のサポートをPythonに加える。
- 多次元配列を操作するための大規模な高水準の数学関数ライブラリを提供する。
- NumPy自体はC言語で書かれているため、Pythonのリストと比べると高速な処理が可能。
準備 †
インストール †
> pip install numpy
インポート †
>>>import numpy as np
ファースト・ステップ †
1次元配列はベクトルとも言う。
生成 †
- array
>>>np.array([1.0,2.0,3.0])
array([1., 2., 3.])
- arange
>>>np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
- ones(1埋め
>>>np.ones(10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
- zeros(0埋め
>>>np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
- empty
>>>np.empty(5)
array([2.12199579e-314, 6.36598737e-314, 1.06099790e-313, 1.48539705e-313,
1.90979621e-313])
- random.randn(標準正規分布
>>>np.random.randn(10)
array([ 1.33385073, -0.61769365, 1.41045502, -0.18429257, -0.00662791,
-0.09483573, -2.26232104, 0.95660959, -1.02715574, -1.02119134])
確認 †
>>>a=np.array([1.0,2.0,3.0])
- 生
>>>a
array([1., 2., 3.])
- print
>>>print(a)
[1. 2. 3.]
算術計算 †
- 四則演算
2つのNumPy配列を算術計算で処理する。
- 同じ数の要素を持つ配列の要素ごとの計算
>>>x=np.array([1.0,2.0,3.0])
>>>y=np.array([2.0,4.0,6.0])
- その他の計算
>>>x=np.arange(10)
>>>x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
- 平方根の計算
>>>np.sqrt(x)
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
- ネイピア数(自然対数の底)e を底とする累乗
>>>np.exp(x)
array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
2.98095799e+03, 8.10308393e+03])
統計計算 †
標準正規分布
>>>x=np.random.randn(10)
- 符号
>>>np.sign(x)
array([ 1., 1., -1., -1., -1., -1., 1., 1., 1., 1.])
行列 †
行列とは?
- 2次元配列は行列とも言う。
- 行が、1つの添字で表される1つのべクトル
- 列は、ベクトルのn番目の要素をグループ化したもの。
列↓
┌ ┐
行│○ ○│
→│ │
│○ ○│
└ ┘
テンソル †
テンソルとは?
- ベクトルや行列を一般化したものをテンソルと呼ぶ。
- 3次元以上の配列を、テンソル / 多次元配列と呼ぶ。
- 任意の次元の配列
- 3次元の配列は3階テンソル
- 4次元の配列は4階テンソル
- 特別な呼び方
- 0階テンソルをスカラー
- 1階テンソルをベクトル
- 2階テンソルのことを行列
生成 †
- 通常
>>> a=np.array([[1,2],[3,4],[5,6]])
- 型指定
>>> a=np.array([[1,2],[3,4],[5,6]],dtype=np.int32)
- コピー
>>>a=np.array([[1,2],[3,4],[5,6]])
確認 †
- 行列の形状(行数・列数
>>>a.shape
(3, 2)
算術計算 †
- 四則演算
2つのNumPy行列を算術計算で処理する。
- 行列の要素数が同じ
>>>x=np.array([[1, 2], [3, 4]])
>>>y=np.array([[3, 0], [0, 6]])
>>>x+y
array([[ 4, 2],
[ 3, 10]])
- 行列の要素数が異なる
(ブロード・キャスト)
>>>x=np.array([[1, 2], [3, 4]])
>>>y=np.array([10,20])
>>>x+y
array([[11, 22],
[13, 24]])
- 行列の要素数が同じ
>>>x=np.array([[1, 2], [3, 4]])
>>>y=np.array([[3, 0], [0, 6]])
>>>x*y
array([[ 3, 0],
[ 0, 24]])
- 行列の要素数が異なる
(ブロード・キャスト)
>>>x=np.array([[1, 2], [3, 4]])
>>>y=np.array([10,20])
>>>x*y
array([[10, 40],
[30, 80]])
統計計算 †
セカンド・ステップ †
要素へのアクセス †
- 行列
>>> b=np.array([[51, 55], [14, 19], [0, 4]])
>>> print(b)
[[51 55]
[14 19]
[ 0 4]]
インデックス †
- N次配列にN個のインデックスを指定すると要素が取り出せる。
>>>b[0][1]
55
- N次配列にX個のインデックスを指定するとN-X次配列が取り出せる。
>>>b[0]
array([51, 55])
抽出 †
- 比較演算
比較の結果boolの配列が生成されて指定されている。
- 行インデックス
>>>b[np.array([0,1])]
array([[51, 55],
[14, 19]])
- 比較演算
比較の結果boolの配列とか行列などが生成されて指定されている。
ベクトル編集 †
置換 †
- 5より大きい値を調査。
>>>a>5
array([False, False, False, False, False, False, True, True, True, True])
- 特定の値を変換
>>>a[a==5]=0
>>>a
array([0, 1, 2, 3, 4, 0, 6, 7, 8, 9])
要素の追加 †
...
行列編集 †
置換 †
- 15より大きい値を調査。
>>>b>15
array([[ True, True],
[False, True],
[False, False]])
- 特定の値を変換
>>>b[b==55]=99
array([[51, 99],
[14, 19],
[ 0, 4]])
行追加 †
- vstack
2次元で言うと、垂直方向=行追加方向
np.vstack([a, a])
列追加 †
- hstack
2次元でいうと、水平方向=列追加方向にスタック
np.hstack([a, a])
行削除 †
スライシング
列の削除 †
スライシング
要素の追加 †
stackで新規次元を追加してスタックする。
- ベクトル要素が新規次元で(行追加方向に)スタックして新規次元を追加
>>>np.stack([a.flatten(), a.flatten()])
>>>np.stack([a.flatten(), a.flatten()], 0)
array([[51, 55, 14, 19, 0, 4],
[51, 55, 14, 19, 0, 4]])
- 行列の要素が新規次元でスタックして新規次元を追加
>>>np.stack([a, a])
>>>np.stack([a, a], 0)
array([[[51, 55],
[14, 19],
[ 0, 4]],
[[51, 55],
[14, 19],
[ 0, 4]]])
- ベクトル要素が列の次元で(列追加方向に)スタックして新規次元を追加
>>>np.stack([a.flatten(), a.flatten()], 1)
array([[51, 51],
[55, 55],
[14, 14],
[19, 19],
[ 0, 0],
[ 4, 4]])
- 行列の要素が行の次元でスタックして新規次元を追加
>>>np.stack([a, a], 1)
array([[[51, 55],
[51, 55]],
[[14, 19],
[14, 19]],
[[ 0, 4],
[ 0, 4]]])
- 行列の要素が列の次元でスタックして新規次元を追加
>>>np.stack([a, a], 2)
array([[[51, 51],
[55, 55]],
[[14, 14],
[19, 19]],
[[ 0, 0],
[ 4, 4]]])
サード・ステップ †
型の変換 †
要素の型の変換 †
配列でも、行列でも。
>>> b=np.array(a,dtype=np.int32)
LIST ⇔ NP型変換 †
- LIST → NP
コレについては、生成の所で既出(np.arrayを使う)。
- LIST ← NP
ndarray.tolist()メソッドが使える。
np_arr.tolist()
配列・行列変換 †
行列の配列化 †
(機械学習ライブラリ入力用)
- 行ベクトル(横ベクトル)化
b=a[0,:] # 1行目、全列スライス
- 列ベクトル(縦ベクトル)化
b=a[:,0] # 1列目、全行スライス
配列の行列化 †
(機械学習ライブラリ入力用)
- reshape
>>>c=b.reshape(1, -1)
- np.newaxis
>>>c=b[np.newaxis, :]
- reshape
>>>c=b.reshape(-1, 1)
- np.newaxis
>>>c=b[:, np.newaxis]
行列の変換 †
転置行列 †
>>> a=np.array([[51, 55], [14, 19], [0, 4]])
>>> print(a)
[[51 55]
[14 19]
[ 0 4]]
次元の入れ替え †
行(0)と列(1)が入れ替わる。
転置と同じだが、2次元以上のn次元行列にも適用可能。
>>> a=np.array([[51, 55], [14, 19], [0, 4]])
>>> print(a)
>>> a=a.transpose([1, 0])
>>> print(a)
再構成 †
>>>a=np.arange(0, 12)
- numpy.reshape
>>>np.reshape(a,[4,3])
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>>np.reshape(a,[3,2,2])
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])
- ndarray.reshape
>>>a.reshape([4,3])
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>>a.reshape([3,2,2])
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])
One-Hotエンコーディング †
>>> a=np.array([[0,1,2,3,4,5,6,7,8,9]])
>>> print(a)
[[0 1 2 3 4 5 6 7 8 9]]
エンコーディング †
デコーディング †
- np.argmaxを使う。
b.argmax(axis=1)
4thステップ †
ベクトルの積算(ドット積 = 内積) †
>>>a=np.array([1,2,3,4])
>>>b=np.array([10,20,30,40])
データの生成 †
ベクトルを行列化する。
>>> a=a.reshape(1, -1)
>>> b=b.reshape(1, -1).T # 転置行列に
計算方法 †
交換法則が成立 †
行列では、交換法則の不成立になるが、
ベクトルの場合は成立する(ただし転置が必要)。
>>>a@b
>>>b.T@a.T
>>>np.dot(a,b)
>>>np.dot(b.T,a.T)
行列の積算(ドット積 ≠ 内積) †
A行列 * B行列 =C行列
- A行列の列数とB行列の行数が一致ししている必要がある。
- 計算後のC行列は、A行列の行数 * B行列の列数の行列になる。
2行2列の場合 †
┌ ┐┌ ┐ ┌ ┐
│a1 b1││a2 b2│ │a1a2+b1c2 a1b2+b1d2│
│ ││ │ = │ │
│c1 d1││c2 d2│ │c1a2+d1c2 c1b2+d1d2│
└ ┘└ ┘ └ ┘
A行列 B行列 C行列
2行2列 2行2列 2行2列
x行y列の場合 †
計算後のC行列は、A行列の行数 * B行列の列数の行列になる。
- ベクトルと行列との計算では、
ベクトルが行列形状に拡張され計算される。
┌ ┐┌ ┐ ┌ ┐┌ ┐ ┌ ┐
│a1 b1││a2│ │a1 b1││a2 0│ │a1a2+b1b2│
│ ││ │ = │ ││ │ =│ │
│c1 d1││b2│ │c1 d1││b2 0│ │c1a2+d1b2│
└ ┘└ ┘ └ ┘└ ┘ └ ┘
A行列 B行列 C行列
2行2列 2行1列 2行1列
- A行列の列数とB行列の行数が一致ししている必要がある。
┌ ┐┌ ┐ ┌ ┐
│a1 b1││a2 b2 c2 d2│ │a1a2+b1e2 a1b2+b1f2 a1c2+b1g2 a1d2+b1h2│
│ ││ │ │ │
│c1 d1││e2 f2 g2 h2│ = │c1a2+d1e2 c1b2+d1f2 c1c2+d1g2 c1d2+d1h2│
│ │└ ┘ │ │
│e1 f1│ │e1a2+f1e2 e1b2+f1f2 e1c2+f1g2 e1d2+f1h2│
└ ┘ └ ┘
A行列 B行列 C行列
3行2列 2行4列 3行4列
計算方法 †
要素ごとの掛け算でないことに注意
- データ生成
>>>a=np.array([[1,2,3],[4,5,6]])
>>>b=np.array([[1,2],[3,4],[5,6]])
>>>c=np.array([[1,2],[3,4]])
>>>d=np.array([7,8])
>>>a
array([[1, 2, 3],
[4, 5, 6]])
>>>b
array([[1, 2],
[3, 4],
[5, 6]])
>>>c
array([[1, 2],
[3, 4]])
>>>d
array([7, 8])
- 演算子
@(ドット積)演算子を使用する。
>>>a@b
array([[22, 28],
[49, 64]])
>>>b@c
array([[ 7, 10],
[15, 22],
[23, 34]])
>>>b@d
array([23, 53, 83])
>>>a@c # A行列の列数とB行列の行数が一致しない。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)
- メソッド
dot(ドット積)メソッドを使用する。
>>>np.dot(a,b)
array([[22, 28],
[49, 64]])
>>>np.dot(b,c)
array([[ 7, 10],
[15, 22],
[23, 34]])
>>>np.dot(b,d)
array([23, 53, 83])
>>>np.dot(a,c) # A行列の列数とB行列の行数が一致しない。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: shapes (2,3) and (2,2) not aligned: 3 (dim 1) != 2 (dim 0)
信号処理 †
... †
参考 †
|