numpy中數(shù)據(jù)格式有array和mat,乘法有普通乘號x和dot,對于初學(xué)者(本人也是初學(xué)者)來說太容易迷糊了。下面記錄一點心得。
先說結(jié)論:dot是遵循矩陣乘法的法則;普通乘號x遵循的法則既有矩陣乘法法則,也有逐元素相乘的法則,具體看相乘的兩個數(shù)組的數(shù)據(jù)類型。
普通乘號X
1.array相乘
當(dāng)兩個array格式的數(shù)組相乘時,結(jié)果實際上是逐元素相乘。
In [60]: a = np.array([1, 2, 3, 4])
In [61]: b = np.array([2, 2, 3, 3])
In [62]: a * b
Out[62]: array([ 2, 4, 9, 12])
-----------------------------
In [63]: b = np.array([2])
In [64]: a * b
Out[64]: array([2, 4, 6, 8])
-----------------------------------
In [70]: b = np.array([2, 3])
In [71]: b
Out[71]: array([2, 3])
In [72]: a
Out[72]:
array([[1, 2],
[3, 4]])
In [73]: a * b # 此時相當(dāng)于將b擴(kuò)展成array([[2, 3],[2, 3]])
Out[73]:
array([[ 2, 6],
[ 6, 12]])
--------------------------------
In [74]: b.shape = (2, 1)
In [75]: b
Out[75]:
array([[2],
[3]])
In [76]: b * a # 此時相當(dāng)于將b擴(kuò)展成array([[2, 2], [3, 3]])
Out[76]:
array([[ 2, 4],
[ 9, 12]])
In [77]: a * b
Out[77]:
array([[ 2, 4],
[ 9, 12]])
2.mat相乘
當(dāng)兩個mat格式的數(shù)組相乘時,結(jié)果遵循矩陣相乘法則。
3.array與mat相乘
當(dāng)array與mat格式的數(shù)組相乘時,結(jié)果遵循矩陣相乘法則。
In [83]: a
Out[83]:
array([[1, 2],
[3, 4]])
In [84]: b = np.mat('[2 2];[3 3]')
In [85]: b
Out[85]:
matrix([[2, 2],
[3, 3]])
In [86]: a * b # 注意a * b的結(jié)果與b * a的結(jié)果不一致
Out[86]:
matrix([[ 8, 8],
[18, 18]])
In [87]: b * a
Out[87]:
matrix([[ 8, 12],
[12, 18]])
---------------------------------
In [90]: a
Out[90]:
matrix([[1, 2],
[3, 4]])
In [91]: b = np.array([2, 3])
In [92]: b
Out[92]: array([2, 3])
In [93]: a * b # 注意此時出錯了,因為不符合矩陣相乘法則
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-93-50927f39610b> in <module>()
----> 1 a * b
/usr/local/lib/python3.6/site-packages/numpy/matrixlib/defmatrix.py in __mul__(self, other)
341 if isinstance(other, (N.ndarray, list, tuple)) :
342 # This promotes 1-D vectors to row vectors
--> 343 return N.dot(self, asmatrix(other))
344 if isscalar(other) or not hasattr(other, '__rmul__') :
345 return N.dot(self, other)
ValueError: shapes (2,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)
In [94]: b * a
Out[94]: matrix([[11, 16]])
dot
dot實際上采用的就是矩陣的乘法規(guī)則,不管是什么數(shù)據(jù)格式。如下示例:
1.array相乘
In [2]: a = np.array([[1, 2], [3, 4]])
In [3]: a
Out[3]:
array([[1, 2],
[3, 4]])
In [4]: b = np.array([[2, 3], [2, 3]])
In [5]: b
Out[5]:
array([[2, 3],
[2, 3]])
In [6]: a.dot(b) # 此時就是矩陣a x 矩陣b的結(jié)果
Out[6]:
array([[ 6, 9],
[14, 21]])
下面再舉一個反常的例子:
In [7]: b = np.array([2, 3])
In [8]: a.dot(b)
Out[8]: array([ 8, 18])
如何理解這個例子呢?若按照矩陣的乘法法則,則a x b 應(yīng)該會報錯啊。實際上,此時的a.dot(b)可以理解為a x b.T的結(jié)果,再轉(zhuǎn)置回來,如下所示:
In [9]: c = b.reshape((2, 1))
In [10]: c
Out[10]:
array([[2],
[3]])
In [11]: a.dot(c)
Out[11]:
array([[ 8],
[18]])
In [12]: np.mat(a) * c
Out[12]:
matrix([[ 8],
[18]])
2.其余mat相乘及mat與array相乘,都是遵循矩陣的乘法法則。