「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
多次元配列における数値計算を効率的に行うことをサポートする数学関数ライブラリ
> pip install numpy
>>>import numpy as np
1次元配列はベクトルとも言う。
>>>np.array([1.0,2.0,3.0]) array([1., 2., 3.])
>>>np.arange(10) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>np.ones(10) array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
>>>np.zeros(10) array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>>np.empty(5)
array([2.12199579e-314, 6.36598737e-314, 1.06099790e-313, 1.48539705e-313,
1.90979621e-313])>>>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(a) [1. 2. 3.]
>>>type(a) <class 'numpy.ndarray'>
>>>np.ndim(a) # 配列の次元 1
>>>a.shape # 次元の形状 (3,)
>>>a.shape[0] # 次元の要素数 3
>>>a.dtype # 要素のデータ型
dtype('float64')
同じ数の要素を持つ2つのNumPy配列を算術計算で処理する。
>>>x=np.array([1.0,2.0,3.0]) >>>y=np.array([2.0,4.0,6.0])
>>>x+y array([ 3., 6., 9.])
>>>x-y array([-1., -2., -3.])
>>>x*y array([ 2., 8., 18.])
>>>x/y array([ 0.5, 0.5, 0.5])
>>>x=np.arange(10) >>>x
>>>np.sqrt(x)
array([0. , 1. , 1.41421356, 1.73205081, 2. ,
2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])>>>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.])
>>>x.mean() 0.02713878708811851
>>>x.std() 1.2305510107988773
行列とは?
列↓ ┌ ┐ 行│○ ○│ →│ │ │○ ○│ └ ┘
テンソルとは?
>>> a=np.array([[1,2],[3,4],[5,6]])
>>> a=np.array([[1,2],[3,4],[5,6]],dtype=np.int32)
>>>a
>>> print(a) [[1 2] [3 4] [5 6]]
>>>np.ndim(a) # 配列の次元 2
>>>a.shape # 行列の形状(行数・列数 (3, 2)
>>>a.dtype # 行列要素のデータ型
dtype('int32')
>>>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]])>>> a=np.array([[51, 55], [14, 19], [0, 4]]) >>> print(a) [[51 55] [14 19] [ 0 4]]
>>>a[0][1] 55
>>>a[0] array([51, 55])
>>>a[0,1:2] array([55]) >>>a[1:2,0] array([14])
>>>a[np.array([0,1])]
array([[51, 55],
[14, 19]])>>>a[a>15] array([51, 55, 19])
>>>a[a[:,1]==19] array([[14, 19]])
>>>a>15
array([[ True, True],
[False, True],
[False, False]])>>>a[a==55]=99
array([[51, 99],
[14, 19],
[ 0, 4]])>>>a=np.array(a,dtype=np.int64) # 要素の型をint64に変換
>>> b=a.flatten() >>> print(b) [51 55 14 19 0 4]
b=a[0,:] # 1行目、全列スライス
b=a[:,0] # 1列目、全行スライス
>>>c=b.reshape(1, -1)
>>>c=b[np.newaxis, :]
>>>c=b.reshape(-1, 1)
>>>c=b[:, np.newaxis]
>>>c.flatten()
>>>c.reshape(-1)
np.vstack([a, a])
np.concatenate([a, a]) np.concatenate([a, a], 0)
np.hstack([a, a])
np.concatenate([a, a], 1)
np.stack([a.flatten(), a.flatten()]) np.stack([a.flatten(), a.flatten()], 0)
np.stack([a, a]) np.stack([a, a], 0)
np.stack([a.flatten(), a.flatten()], 1)
np.stack([a, a], 1)
np.stack([a, a], 2)
スカラ値や異なる形状の配列と計算を行う。
配列とスカラ値との計算では、スカラ値が配列形状に拡張され計算される。
>>>x=np.array([1.0,2.0,3.0]) >>>x/2.0 array([0.5, 1. , 1.5])
>>>a=np.array([[1, 2], [3, 4]])
>>>a*10
array([[10, 20],
[30, 40]])→ 行列の積算
np_arr.tolist()
>>> a=np.array([[51, 55], [14, 19], [0, 4]]) >>> print(a) [[51 55] [14 19] [ 0 4]]
>>>print(a.T) [[51 14 0] [55 19 4]]
>>>print(a.transpose()) [[51 14 0] [55 19 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)
>>>np.reshape(a,[4,3])
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>>np.reshape(a,[4,3])
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])>>>a.reshape([4,3])
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>>a.reshape([4,3])
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])>>> 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]]
b = np_utils.to_categorical(a, num_classes=10).astype('i') b = np.identity(10)[a].astype('i')print((b.argmax(axis=1) == a).all())
A行列 * B行列 =C行列
┌ ┐┌ ┐ ┌ ┐ │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列
計算後の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列
┌ ┐┌ ┐ ┌ ┐ │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)
>>>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)>>>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
>>>np.dot(a,b)
行列では、交換法則の不成立になるが、
ベクトルの場合は成立する(ただし転置が必要)。
>>>a@b >>>b.T@a.T
>>>np.dot(a,b) >>>np.dot(b.T,a.T)