NumPy - izudon/izudon.github.io GitHub Wiki

上記書籍を読んだ限りで抑えておくべき知識を整理する。

N次元配列

  • NumPy には N次元配列という概念はある。
  • が、行列とか、行ベクトル、列ベクトル、N次元べクトルといった概念は、ないか、 あってもサブ的な概念ポジションでしかないらしい。
>>> x = np.array([1,2,3])
>>> x.__class__
<class 'numpy.ndarray'>
>>> x.shape  #-- 要素数3の
(3,)
>>> x.ndim   #-- 1次元配列
1

>>> x = np.array([1,2,3](/izudon/izudon.github.io/wiki/1,2,3)) #-- [] が2重に増えただけだが・・・
>>> x.__class__
<class 'numpy.ndarray'>
>>> x.shape  #-- 第0軸要素数1、第1軸要素数3の・・・
(1, 3)
>>> x.ndim   #-- 2次元配列
2

>>> x = np.array([[1,2,3](/izudon/izudon.github.io/wiki/[1,2,3)]) #-- 3重にしてみる
>>> x.__class__
<class 'numpy.ndarray'>
>>> x.shape  #-- 第0軸要素数1、第1軸要素数1、第2軸要素数3の・・・
(1, 1, 3)
>>> x.ndim   #-- 3次元配列
3
>>> W = np.array([1,2,3],[4,5,6](/izudon/izudon.github.io/wiki/1,2,3],[4,5,6))
>>> W.__class__
<class 'numpy.ndarray'>
>>> W.shape  #-- 第0軸要素数2、第1軸要素数3の・・・
(2, 3)
>>> W.ndim   #-- 2次元配列(-> いわゆる行列)
2
>>> W
array([[1, 2, 3],   #-- この表現出力を見れば(コンソール表現上やむを得ないからだろうが)
       [4, 5, 6]])  #-- 行列を行ベクトルの集合とみているらしきことがわかる。
>>> W.shape         #-- 行列になっている場合は、.shape の出力結果を
(2, 3)              #-- そのまま「2行3列の行列」と読んでよくなる。
>>> W = np.array( [[1,1],[2,2],[3,3](/izudon/izudon.github.io/wiki/[1,1],[2,2],[3,3),[4,4],[5,5],[6,6](/izudon/izudon.github.io/wiki/4,4],[5,5],[6,6)] )
>>> W
array([[[1, 1],     #-- 3次元配列の第0軸にも複数要素が並んだ場合
        [2, 2],     #-- こうやって1面ずつ表示していく
        [3, 3]],

       [[4, 4],     #-- 2面目
        [5, 5],
        [6, 6]]])

演算

  • 演算はすべて要素ごとの演算となる。
  • 足りない次元は追加され、空白のポジションは自己コピーで補われて用いられる。
>>> x = np.array([[1,2,3](/izudon/izudon.github.io/wiki/[1,2,3)])
>>> W = np.array([1,2,3],[4,5,6](/izudon/izudon.github.io/wiki/1,2,3],[4,5,6))
>>> x + W             #-- 下から2次目の要素数で x が1つ足りないので
array([[2, 4, 6],    #-- 同じものがコピーされて [[1,2,3],[1,2,3](/izudon/izudon.github.io/wiki/[2,-4,-6],----#---同じものがコピーされて-[[1,2,3],[1,2,3) 
        [5, 7, 9]]])  #-- として計算された。
>>> ( x + W ).shape   #-- .shape (1,1,3) と .shape (2,3) の足し算。
(1, 2, 3)             #-- 結果は .shape (1,2,3) になる。
>>> ( x + W ).ndim    #-- 要するに下位次元に揃えて演算される。
3
>>> x * W             #-- 掛け算も同様
array([[[ 1,  4,  9],
        [ 4, 10, 18]]])
>>> 10 * W            #-- スカラとの演算もやはり「各要素に」かかる。
array([[10, 20, 30],  #-- あるいはやはり拡張されたと考えても良い。
       [40, 50, 60]]) #-- 10 -> [10,10,10],[10,10,10](/izudon/izudon.github.io/wiki/10,10,10],[10,10,10)

行列の積

  • いわゆる「行列の積」は、従って、メソッドにお願いする。
  • .shape (p,q) と .shape (q,r) の行列の積は .shape (p,r) になる。
    (pxq 行列と qxr 行列 の積は pxr 行列になる)
  • かける方の列数とかけられるほうの行数が異なる場合はもちろんエラー。
>>> A = np.array([1,2,3],[4,5,6](/izudon/izudon.github.io/wiki/1,2,3],[4,5,6))
>>> B = np.array([1,2],[3,4],[5,6](/izudon/izudon.github.io/wiki/1,2],[3,4],[5,6))
>>> np.dot(A,B)
array([[22, 28],
       [49, 64]])
>>> np.dot(B,A)
array([[ 9, 12, 15],
       [19, 26, 33],
       [29, 40, 51]])

repeatsum

  • 軸を指定して sum
    • => その軸に沿って総和(まとめちゃう)。
    • => 次元が一つ減る。
  • keepdims=True で、次元減らさず。
    • => .shape が元と変わらないN次元配列になる。
    • => 但しその軸の要素数は1となる。
>>> import numpy as np
>>> D, N = 8, 7
>>> x = np.random.randn( 1, D )
>>> y = np.random.randn( x, N, axis=0 )

>>> dy = np.random.randn( N, D )
>>> dx = np.sum( dy, axis=0, keepdims=True )