numpyでは、配列(numpy.array
)と行列(numpy.matrix
)を扱うことができ、両者間の演算であっても基本的にはスムーズに行うことができます。
しかし*
(乗算演算子)では注意が必要です。
通常、配列同士の演算ではこの記号はアダマール積を表します。行列積を求めたい場合にはnp.dot()
または@
演算子を使用します。
しかし、*
演算子で求まるのは常にアダマール積だと言う理解は危険で、行列同士の演算で*
を用いた場合は、アダマール積ではなく行列積が求まることに注意が必要です。当然@
で求まるのも行列積です。
また、一方が行列でもう一方が配列だった場合、自動的にどちらも行列にキャストされるため、求まるのは行列積であり、返り値の型もnumpy.matrix
になります。
演算によって得られる結果とその型を表にまとめると以下のようになります。
* 演算子 |
@ 演算子 |
|
---|---|---|
両方が配列 |
アダマール積 (配列) |
行列積 (配列) |
両方が行列 | 行列積 (行列) |
行列積 (行列) |
片方が配列で片方が行列 | 行列積 (行列) |
行列積 (行列) |
import numpy as np
a = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
a_array = np.array(a)
a_matrix = np.matrix(a)
b = [
[1, -1, 0],
[1, -1, 0],
[1, -1, 0]
]
b_array = np.array(b)
b_matrix = np.matrix(b)
# *演算子
# 配列 * 配列 -> アダマール積(配列)
c = a_array * b
print(c, type(c))
# [[ 1 -2 0]
# [ 4 -5 0]
# [ 7 -8 0]] <class 'numpy.ndarray'>
# 行列 * 行列 -> 行列積(行列)
c = a_matrix * b_matrix
print(c, type(c))
# [[ 6 -6 0]
# [ 15 -15 0]
# [ 24 -24 0]] <class 'numpy.matrix'>
# 行列 * 配列 -> 行列積(行列)
c = a_matrix * b_array
print(c, type(c))
# [[ 6 -6 0]
# [ 15 -15 0]
# [ 24 -24 0]] <class 'numpy.matrix'>
# @演算子
# 配列 @ 配列 -> 行列積(配列)
c = a_array @ b_array
print(c, type(c))
# [[ 6 -6 0]
# [ 15 -15 0]
# [ 24 -24 0]] <class 'numpy.ndarray'>
# 行列 @ 配列 -> 行列積(行列)
c = a_matrix @ b_array
print(c, type(c))
# [[ 6 -6 0]
# [ 15 -15 0]
# [ 24 -24 0]] <class 'numpy.matrix'>