記事

Numpy & Scipy - 1.5 行列の基本操作 (3)

Numpy & Scipy - 1.5 行列の基本操作 (3)
Visitors


同じサイズの行列、ベクトルの足し算・引き算

$A = \begin{bmatrix} 1 & 2 \ 3 & 4 \end{bmatrix}$ $B = \begin{bmatrix} 5 & 6 \ 7 & 8 \end{bmatrix}$

1
2
3
4
5
6
7
A = np.array([[1,2], [3,4]])

B = np.array([[5,6],[7,8]])

C = A + B

C = A - B
  • ベクトル(1D array)も同様に足し算、引き算が可能です。
  • shapeさえ同じなら問題ありません。



サイズの大きな行列を簡単に作る

$ A = \begin{bmatrix} 2 & 1 & 0 & 0 & 0 \ -1 & 2 & 1 & 0 & 0 \ 0 & -1 & 2 & 1 & 0 \ 0 & 0 & -1 & 2 & 1 \ 0 & 0 & 0 & -1 & 2 \end{bmatrix} = \begin{bmatrix} 0 & 0 & 0 & 0 & 0 \ -1 & 0 & 0 & 0 & 0 \ 0 & -1 & 0 & 0 & 0 \ 0 & 0 & -1 & 0 & 0 \ 0 & 0 & 0 & -1 & 0 \end{bmatrix} + \begin{bmatrix} 2 & 0 & 0 & 0 & 0 \ 0 & 2 & 0 & 0 & 0 \ 0 & 0 & 2 & 0 & 0 \ 0 & 0 & 0 & 2 & 0 \ 0 & 0 & 0 & 0 & 2 \end{bmatrix} + \begin{bmatrix} 0 & 1 & 0 & 0 & 0 \ 0 & 0 & 1 & 0 & 0 \ 0 & 0 & 0 & 1 & 0 \ 0 & 0 & 0 & 0 & 1 \ 0 & 0 & 0 & 0 & 0 \end{bmatrix} $

  • ここで、bandごとに np.ones を活用して1D arrayとして抽出した後、スカラー値を掛けましょう。

$k = -1$ の場合
$ b_1 = \begin{bmatrix} -1 & -1 & -1 & -1 \end{bmatrix} $

1
b1 = (-1)*np.ones((4,))


$k = 0$ の場合
$ b_2 = \begin{bmatrix} 2 & 2 & 2 & 2 & 2 \end{bmatrix} $

1
b2 = (2)*np.ones((5,))


$k = 1$ の場合
$ b_3 = \begin{bmatrix} 1 & 1 & 1 & 1 \end{bmatrix} $

1
b3 = (1)*np.ones((4,))


  • その後、np.diag 機能を活用して1D arrayたちをそれぞれ最大サイズ(k=0)を基準とした行列にした後、足せば良いです。
1
2
3
A = np.diag(b1, k=-1) + np.diag(b2, k=0) + np.diag(b3, k=1)

print(A)
1
2
3
4
5
[[ 2.  1.  0.  0.  0.]
 [-1.  2.  1.  0.  0.]
 [ 0. -1.  2.  1.  0.]
 [ 0.  0. -1.  2.  1.]
 [ 0.  0.  0. -1.  2.]]



スカラーと行列の足し算 (r + A)

  • 数学的にはあり得ませんが、Pythonでは可能です…
  • すべての entry にスカラーを足します。ベクトルも同様です。
1
2
3
4
5
6
7
A = np.array([[1,2],[3,4]])

r = 5

result = r + A # = A + r

print(result)
1
2
[[6 7]
 [8 9]]



行列と行列の要素ごとの掛け算・割り算 (A * B) (A / B)

  • 行列の乗算 (matrix multiplication) ではないことに注意しましょう。A @ Bnp.matmul とは全く異なります!!
  • shapeが同じ行列同士で掛け算ができます。
  • 同じインデックスの entry 同士を掛けて結果として返します。ベクトルも同様です。
1
2
3
4
5
6
A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])

result = A * B # = B * A

print(result)
1
2
[[ 5 12]
 [21 32]]


  • 割り算も同様です。
  • 逆行列を意味するのではなく、単なる割り算です。
1
2
3
4
5
6
A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])

result = A / B # = B / A

print(result)
1
2
[[0.2        0.33333333]
 [0.42857143 0.5       ]]



行列とベクトルの要素ごとの掛け算・割り算 (A * b) (A / b)

  • matrix-vector product ではないことに注意しましょう。
  • shapeが異なる状況ですが可能です…
  • 行列の列(column)の数とベクトルのサイズが同じでなければなりません。(A.shape[1] == b.shape[0])
  • 割り算の場合、A / bb / A は結果値が異なります。演算方法自体が異なるためです。

Desktop View

  • 上の写真の同じ色の領域同士で掛け算・割り算が行われます。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
A = np.array([[1,2],[3,4]])
b = np.array([2,4])

result = A * b

print(result)

result = A / b

print(result)

result = b / A # = b * (1 / A) と考えれば良いです。

print(result)
1
2
3
4
5
6
7
8
[[ 2  8]
 [ 6 16]]

 [[0.5 0.5]
 [1.5 1. ]]

[[2.         2.        ]
 [0.66666667 1.        ]]



インデックス配列を使用して行列の一部を再構築する

1
2
3
A = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[-1,-2,-3,-4,-5]])

print(A)


1
2
3
4
5
6
7
8
what_i_want = A[[1,2,0,3], : ]

# or

idx = [1,2,0,3]
what_i_want = A[idx, :]

print(what_i_want)
1
2
3
4
5
6
7
8
9
10
11
# matrix A
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [-1 -2 -3 -4 -5]]

# index array
[[ 6  7  8  9 10]
 [11 12 13 14 15]
 [ 1  2  3  4  5]
 [-1 -2 -3 -4 -5]]


  • 行 (row) だけを取り出す
1
2
3
4
5
idx = [2,1]

what_i_want = A[idx, :]

print(what_i_want)
1
2
[[11 12 13 14 15]
 [ 6  7  8  9 10]]


  • 列 (column) も可能
1
2
3
4
5
idx = [4,1,2]

what_i_want = A[:, idx]

print(what_i_want)
1
2
3
4
[[ 5  2  3]
 [10  7  8]
 [15 12 13]
 [-5 -2 -3]]


  • 二つの複合
1
2
3
4
5
6
idx_r = [2,3,0] # row
idx_c = [2,1,3] # column

what_i_want = A[idx_r, :][:, idx_c] # =  A[:, idx_c][idx_r, :]

print(what_i_want)
1
2
3
[[13 12 14]
 [-3 -2 -4]
 [ 3  2  4]]
この記事は著者の CC BY 4.0 ライセンスの下で提供されています。