python中使用numpy包的向量矩陣相乘np.dot和np.matmul實(shí)現(xiàn)
一直對(duì)np的線性運(yùn)算不太清晰,正好上課講到了,做一個(gè)筆記整個(gè)理解一下
1.向量和矩陣
在numpy中,一重方括號(hào)表示的是向量vector,vector沒(méi)有行列的概念。二重方括號(hào)表示矩陣matrix,有行列。
代碼顯示如下:
import numpy as np a=np.array([1,2,3]) a.shape #(3,) b=np.array([[1,2,3],[3,4,5]]) b.shape #(2, 3) c=np.array([[1],[2],[3]]) c.shape #(3, 1)
即使[1,2,3]、[[1,2,3]]看起來(lái)內(nèi)容一樣 使用過(guò)程中也會(huì)有完全不一樣的變化。下面以向量乘法為例解釋。
2.向量和向量乘法
1.* 對(duì)應(yīng)對(duì)應(yīng)位置相乘
普通的*:在numpy里表示普通的對(duì)應(yīng)位置相乘,注意相乘的兩個(gè)向量、矩陣要保證維數(shù)相同
a1=np.array([1,2,3]) a2=np.array([1,2,3]) a1*a2 #array([1, 4, 9]) b1=np.array([[1,2,3]]) b2=np.array([[1,2,3]]) b1*b2 #array([[1, 4, 9]]) b1=np.array([[1,2,3],[3,4,5]]) b2=np.array([[1,2,3],[3,4,5]]) b1*b2 # array([[ 1, 4, 9], # [ 9, 16, 25]])
2.廣播機(jī)制
如果單純出現(xiàn)維數(shù)對(duì)不上,python會(huì)報(bào)error
b1=np.array([[1,2]]) b2=np.array([[1,2,3]]) b1*b2 #operands could not be broadcast together with shapes (1,2) (1,3)
但是,還有一種情況會(huì)出現(xiàn)乘出來(lái)一個(gè)好大的矩陣,這個(gè)情況常出現(xiàn)在無(wú)意之中把行、列的數(shù)字搞反的情況下。被稱為廣播機(jī)制,需要兩個(gè)乘子都有一個(gè)維數(shù)是1,如果是對(duì)不上且不為1就會(huì)報(bào)錯(cuò)
在普通的對(duì)應(yīng)位置相乘,會(huì)出現(xiàn)
a1=np.array([1,2,3]) a3=np.array([[1],[2],[3]]) a1*a3#broadcast together # array([[1, 2, 3], # [2, 4, 6], # [3, 6, 9]])
倒過(guò)來(lái)也會(huì)出現(xiàn)
a1=np.array([1,2,3]) a3=np.array([[1],[2],[3]]) a3*a1#broadcast together # array([[1, 2, 3], # [2, 4, 6], # [3, 6, 9]])
3.向量點(diǎn)乘np.dot
必須要(行向量,列向量)形式的輸入
a1=np.array([1,2,3]) a3=np.array([[1],[2],[3]]) np.dot(a3,a1) #array([14]) #ValueError: shapes (3,1) and (3,) not aligned: 1 (dim 1) != 3 (dim 0)
都是行向量,不行
b1=np.array([[1,2,3]]) b2=np.array([[1,2,3]]) np.dot(b1,b2) #shapes (1,3) and (1,3) not aligned: 3 (dim 1) != 1 (dim 0)
都是列向量,觸發(fā)廣播機(jī)制
a1=np.array([[1,2,3]]) a3=np.array([[1],[2],[3]]) np.dot(a3,a1) # array([[1, 2, 3], # [2, 4, 6], # [3, 6, 9]])
3.矩陣和向量乘法
1.對(duì)應(yīng)位置相乘
如果單純采用*的方式進(jìn)行矩陣和向量乘法,那就是廣播機(jī)制
矩陣+向量
A1=np.array([[1,2,3],[2,3,4]]) b1=np.array([1,2,3]) A1*b1 #broadcast together # array([[ 1, 4, 9], # [ 2, 6, 12]])
對(duì)應(yīng)的向量如果是矩陣形式,結(jié)果相同
A2=np.array([[1,2,3],[2,3,4]]) b2=np.array([[1,2,3]]) A2*b2 #broadcast together # array([[ 1, 4, 9], # [ 2, 6, 12]])
相似的,如果維數(shù)對(duì)不上,不會(huì)觸發(fā)廣播機(jī)制
A3=np.array([[1,2,3],[2,3,4]]) b3=np.array([[1],[2],[3]]) A3*b3 #operands could not be broadcast together with shapes (2,3) (3,1)
2.矩陣乘法
如果真正想要算矩陣*向量的矩陣乘法,要用np.dot
A4=np.array([[1,2,3],[2,3,4]]) b4=np.array([1,2,3]) np.dot(A4,b4)#dot product #array([14, 20])
列向量也有類似結(jié)果
A4=np.array([[1,2,3],[2,3,4]]) b4=np.array([[1],[2],[3]]) np.dot(A4,b4)#dot product # array([[14], # [20]])
4.矩陣矩陣乘法
1.直接相乘
同樣,也是對(duì)應(yīng)位置相乘
A4=np.array([[1,2,3],[2,3,4]]) B4=np.array([[1,2,3],[4,5,6]]) A4*B4 # array([[ 1, 4, 9], # [ 8, 15, 24]])
有廣播機(jī)制
A4=np.array([[1,2,3],[2,3,4]]) B4=np.array([[1,2,3]]) A4*B4 # array([[ 1, 4, 9], # [ 2, 6, 12]])
2.np.dot
需要第一個(gè)的列數(shù)和第二個(gè)的行數(shù)相對(duì)應(yīng)
A4=np.array([[1,2,3],[2,3,4]]) B4=np.array([[1,2,3],[4,5,6]]) np.dot(A4,B4.T) # array([[14, 32], # [20, 47]]) A5=np.array([[1,2,3],[2,3,4]]) B5=np.array([[1,2,3],[4,5,6],[7,8,9]]) np.dot(A5,B5) # array([[30, 36, 42], # [42, 51, 60]])
對(duì)不上會(huì)報(bào)錯(cuò)
A4=np.array([[1,2,3],[2,3,4]]) B4=np.array([[1,2,3],[4,5,6]]) np.dot(A4,B4) # shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)
5.np.dot 和np.matmul的區(qū)別
主要參考以上博客。
1.在二維(矩陣中),二者是一致的
2.在三維(張量中),二者有差別。
以原博客中的例子為例
a = np.array([i for i in range(12)]).reshape([2,2,3]) b = np.array([i for i in range(12)]).reshape([2,3,2]) """ a [[[ 0 1 2] [ 3 4 5]] [[ 6 7 8] [ 9 10 11]]] b [[[ 0 1] [ 2 3] [ 4 5]] [[ 6 7] [ 8 9] [10 11]]] """
np.dot很清晰,就是a的每一行分別和b的兩層乘起來(lái),于是2*2輸出了四個(gè)“矩陣”(表示成4維的常數(shù)):
""" a11= [ 0 1 2] a12= [ 3 4 5] a21= [ 6 7 8] a22= [ 9 10 11] b [[[ 0 1] [ 2 3] [ 4 5]] [[ 6 7] [ 8 9] [10 11]]] c[:,i,j]=aij*b """
如:
[ 10, 13] =[0 1 2]*[[ 0 1]
[ 2 3]
[ 4 5]]
[ 28, 31]=[0 1 2]*[[ 6 7]
[ 8 9]
[ 10 11]]
>>> np.dot(a,b) array([[[[ 10, 13], [ 28, 31]], [[ 28, 40], [100, 112]]], [[[ 46, 67], [172, 193]], [[ 64, 94], [244, 274]]]]) >>> np.dot(a,b).shape (2, 2, 2, 2)
np.matmul的結(jié)果:
>>> np.matmul(a,b) array([[[ 10, 13], [ 28, 40]], [[172, 193], [244, 274]]]) >>> np.matmul(a,b).shape (2, 2, 2)
可以看出,如果把np.dot視為8行、matmul視為4行的話,matmul正好取第1、3、6、8四行,也就是第一層的前兩行和第二層的后兩行……
直觀理解,ok
到此這篇關(guān)于python中使用numpy包的向量矩陣相乘np.dot和np.matmul實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)numpy向量矩陣相乘np.dot和np.matmul內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python 讀取.shp文件并生成圖幅編號(hào)的實(shí)現(xiàn)思路
這篇文章主要介紹了Python 讀取.shp文件并生成圖幅編號(hào),代碼適用于需要處理和分析地理空間數(shù)據(jù)的場(chǎng)景,如城市規(guī)劃、環(huán)境監(jiān)測(cè)或自然資源管理,其中它可以幫助用戶讀取特定區(qū)域的Shapefile文件,確定其地理邊界,需要的朋友可以參考下2024-05-05Python字符串逆序的實(shí)現(xiàn)方法【一題多解】
今天小編就為大家分享一篇關(guān)于Python字符串逆序的實(shí)現(xiàn)方法【一題多解】,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02python K近鄰算法的kd樹(shù)實(shí)現(xiàn)
這篇文章主要介紹了python K近鄰算法的kd樹(shù)實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09PyQt 實(shí)現(xiàn)使窗口中的元素跟隨窗口大小的變化而變化
今天小編就為大家分享一篇PyQt 實(shí)現(xiàn)使窗口中的元素跟隨窗口大小的變化而變化,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06python使用Turtle庫(kù)繪制動(dòng)態(tài)鐘表
這篇文章主要為大家詳細(xì)介紹了python使用Turtle庫(kù)繪制動(dòng)態(tài)鐘表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11python圖片由RGB空間轉(zhuǎn)成LAB空間的實(shí)現(xiàn)方式
這篇文章主要介紹了python圖片由RGB空間轉(zhuǎn)成LAB空間的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10python uuid生成唯一id或str的最簡(jiǎn)單案例
這篇文章主要介紹了python uuid生成唯一id或str的最簡(jiǎn)單案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01Pycharm報(bào)錯(cuò)Non-zero?exit?code?(2)的完美解決方案
最近在使用pycharm安裝或升級(jí)模塊時(shí)出現(xiàn)了錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于Pycharm報(bào)錯(cuò)Non-zero?exit?code?(2)的完美解決方案,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06Python中join()方法完全使用指南(參數(shù)要求與常見(jiàn)用法)
join()是Python中字符串操作的核心方法之一,但許多開(kāi)發(fā)者在使用時(shí)經(jīng)常遇到TypeError或意外結(jié)果,本文將全面解析' '.join()的參數(shù)要求,通過(guò)實(shí)際示例展示正確用法,并總結(jié)常見(jiàn)問(wèn)題的解決方案,需要的朋友可以參考下2025-06-06