關於Python Numpy庫基礎知識請參考博文:https://www.cnblogs.com/wj-1314/p/9722794.html
Python矩陣的基本用法
mat()函式將目標資料的型別轉化成矩陣(matrix)
1,mat()函式和array()函式的區別
Numpy函式庫中存在兩種不同的資料型別(矩陣matrix和陣列array),都可以用於處理行列表示的數字元素,雖然他們看起來很相似,但是在這兩個資料型別上執行相同的數學運算可能得到不同的結果,其中Numpy函式庫中的matrix與MATLAB中matrices等價。
直接看一個例子:
import numpy as np a = np.mat('1 3;5 7') b = np.mat([[1,2],[3,4]]) print(a) print(b) print(type(a)) print(type(b)) c = np.array([[1,3],[4,5]]) print(c) print(type(c))
結果:
[[1 3] [5 7]] [[1 2] [3 4]] <class 'numpy.matrixlib.defmatrix.matrix'> <class 'numpy.matrixlib.defmatrix.matrix'> [[1 3] [4 5]] <class 'numpy.ndarray'>
首先,mat() 函式與array()函式生成矩陣所需的資料格式有區別,mat()函式中資料可以為字串以分號(;)分割或者為列表形式以逗號(,)分割,而array()函式中資料只能為後者形式。
其次,兩者的型別不同,用mat函式轉換為矩陣後才能進行一些線性代數的操作。
from numpy import * # 構建一個4*4的隨機陣列 array_1 = random.rand(4,4) print(array_1) print(type(array_1)) ''' [[0.12681561 0.26644355 0.03582107 0.71475804] [0.01380711 0.85308305 0.37838406 0.83663897] [0.20034209 0.5736587 0.56692541 0.64008518] [0.97780979 0.129229 0.37688616 0.55341492]] <class 'numpy.ndarray'> ''' # 使用mat函式將陣列轉化為矩陣 matrix_1 = mat(array_1) print(matrix_1) print(type(matrix_1)) ''' [[0.32538457 0.60674013 0.68625186 0.58957989] [0.26465813 0.93378939 0.12944934 0.95064032] [0.65683256 0.01352025 0.11932895 0.9361348 ] [0.11667241 0.16077876 0.50904118 0.44128675]] <class 'numpy.matrixlib.defmatrix.matrix'> '''
2,mat()函式建立常見的矩陣
import numpy as np # 建立一個3*3的零矩陣,矩陣這裡zeros函式的引數是一個tuple型別(3,3) data1 = np.mat(np.zeros((3,3))) print(data1) ''' [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] ''' # 建立一個2*4的1矩陣,預設是浮點型的資料,如果需要時int,可以使用dtype=int data2 = np.mat(np.ones((2,4))) print(data2) ''' [[1. 1. 1. 1.] [1. 1. 1. 1.]] ''' # 這裡使用numpy的random模組 # random.rand(2,2)建立的是一個二維陣列,但是需要將其轉化為matrix data3 = np.mat(np.random.rand(2,2)) print(data3) ''' [[0.62002668 0.55292404] [0.53018371 0.1548954 ]] ''' # 生成一個3*3的0-10之間的隨機整數矩陣,如果需要指定下界可以多加一個引數 data4 = np.mat(np.random.randint(10,size=(3,3))) print(data4) ''' [[0 4 1] [7 9 9] [9 0 4]] ''' # 產生一個2-8之間的隨機整數矩陣 data5 = np.mat(np.random.randint(2,8,size=(2,5))) print(data5) ''' [[4 6 3 3 4] [4 3 3 3 6]] ''' # 產生一個2*2的對角矩陣 data6 = np.mat(np.eye(2,2,dtype=int)) print(data6) ''' [[1 0] [0 1]] ''' # 生成一個對角線為1,2,3的對角矩陣 a1 = [1,2,3] a2 = np.mat(np.diag(a1)) print(a2) ''' [[1 0 0] [0 2 0] [0 0 3]] '''
2.1,zeros
zeros函式是生成指定維數的全0陣列
>>myMat=np.zeros(3) ###生成一個一維的全0陣列 >>print(myMat) >>array([0.,0.,0.]) >>myMat1=np.zeros((3,2)) ####生成一個3*2的全0陣列 >>print(myMat) >>array([[0.,0.], [0.,0.] [0.,0.]])
2.2,ones
ones函式是用於生成一個全1的陣列
>>onesMat=np.ones(3) ###1*3的全1陣列 >>print(onesMat) >>array([1.,1.,1.]) >>onesMat1=np.ones((2,3)) ###2*3的全1陣列 >>print(onesMat1) >>array([[1.,1.,1.],[1.,1.,1.]])
2.3,eye
eye函式使用者生成指定行數的單位矩陣
>>eyeMat=np.eye(4) >>print(eyeMat) >>array([[1.,0.,0.,0.], [0.,1.,0.,0.], [0.,0.,1.,0.,], [0.,0.,0.,1.]])
2.4,full
numpy.full(shape,fill_value=num)
用於建立一個自定義形狀的陣列,可以自己指定一個值,用它填滿整個陣列。
fill_value 用來填充的值,可以是數字,也可以是字串
nd_test = np.full(shape=(2,3,4),fill_value='ai') print(nd_test) array([[['ai', 'ai', 'ai', 'ai'], ['ai', 'ai', 'ai', 'ai'], ['ai', 'ai', 'ai', 'ai']], [['ai', 'ai', 'ai', 'ai'], ['ai', 'ai', 'ai', 'ai'], ['ai', 'ai', 'ai', 'ai']]], dtype='<U2')
2.5 nonzero()
nonzero函式是numpy中用於得到陣列array中非零元素的位置(陣列索引)函式。它的返回值是一個長度為a.ndim(陣列a的軸數)的元組,元組的每個元素都是一個整數陣列,其值為非零元素的下標在對應軸上的值。
只有a中非零元素才會有索引值,那些零值元素沒有索引值,通過a[nonzero(a)]得到所有a中的非零值。
import numpy as np SS = [0,0,0,0] re = np.array(SS) print(SS) print(np.nonzero(re)) ''' [0, 0, 0, 0] (array([], dtype=int64),) '''
a是一維陣列(索引1和索引2的位置上元素的值非零)
>>> import numpy as np >>> a = [0,2,3] >>> b = np.nonzero(a) >>> b (array([1, 2], dtype=int64),) >>> np.array(b).ndim 2
a是多維陣列
from numpy import * b = array([[1,1,1,0,1,1],[1,1,1,0,1,0],[1,1,1,0,1,1]]) print(b) c = nonzero(b) print(c) ''' [[1 1 1 0 1 1] [1 1 1 0 1 0] [1 1 1 0 1 1]] (array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2], dtype=int64), array([0, 1, 2, 4, 5, 0, 1, 2, 4, 0, 1, 2, 4, 5], dtype=int64)) '''
解釋一下:矩陣 b中,b[0,0] b[0,1],b[0,2],b[0,4],b[0,5],b[1,0],b[1,1],b[1,2],b[1,4],b[2,0],b[2,1],b[2,2],b[2,4],b[2,5]元素的值非零。
當使用布林陣列直接作為下標物件護著元組下標物件中有布林陣列時,都相當於用nonzero()將布林陣列轉換成一組整數陣列,然後使用整數陣列進行下標計算。
nonzero(a)返回陣列a中值不為零的元素的下標,它的返回值是一個長度為a.ndim(陣列a的軸數)的元組,元組的每個元素都是一個整數陣列,其值為非零元素的下標在對應軸上的值。例如對於1維布林陣列b1,nonzero(b1)所得到的是一個長度為1的元組,它表示b1[0]和b1[2]的值不為0(FALSE)。
import numpy as np b1 = np.array([True,False,True,False]) res1 = np.nonzero(b1) print(res1) # (array([0, 2], dtype=int64),)
對於二維陣列b2,nonzero(b2)所得到的是一個長度為2的元組,它的第0個元素是陣列a中值不為0的元素的第0個軸的下標,第一個元素則是第1軸的下標,因此從下面得到的結果可知b2[0,0] , n2[0,2]和b2[1,0]的值不為0:
b2 = np.array([[True,False,True],[True,False,False]]) res2 = np.nonzero(b2) print(res2) # (array([0, 0, 1], dtype=int64), array([0, 2, 0], dtype=int64))
當布林陣列直接做維下標時,相當於使用由nonzero()轉換之後的元組作為下標物件:
b3 = np.arange(3*4*5).reshape(3,4,5) res3 = b3[np.nonzero(b2)] print(res3) ''' [[ 0 1 2 3 4] [10 11 12 13 14] [20 21 22 23 24]] '''
3,常見的矩陣運算
3.1,矩陣相乘(*)
就是矩陣的乘法操作,要求左邊矩陣的列和右邊矩陣的行數要一致
from numpy import * ''' 1*2 的矩陣乘以2*1 的矩陣 得到1*1 的矩陣''' a1 = mat([1,2]) print(a1) a2 = mat([[1],[2]]) print(a2) a3 = a1*a2 print(a3) ''' [[1 2]] [[1] [2]] [[5]] '''
3.2,矩陣點乘(multiply)
矩陣點乘則要求矩陣必須維數相等,即M*N維矩陣乘以M*N維矩陣
from numpy import * ''' 矩陣點乘為對應矩陣元素相乘''' a1 = mat([1,1]) print(a1) a2 = mat([2,2]) print(a2) a3 = multiply(a1,a2) print(a3) ''' [[1 1]] [[2 2]] [[2 2]] ''' a1 = mat([2,2]) a2 = a1*2 print(a2) # [[4 4]]
3.3,矩陣求逆變換(.I)
from numpy import * ''' 矩陣求逆變換:求矩陣matrix([[0.5,0],[0,0.5]])的逆矩陣''' a1 = mat(eye(2,2)*0.5) print(a1) a2 = a1.I print(a2) ''' [[0.5 0. ] [0. 0.5]] [[2. 0.] [0. 2.]] '''
3.4,矩陣求轉置(.T)
from numpy import * '''矩陣的轉置''' a1 = mat([[1,1],[0,0]]) print(a1) a2 = a1.T print(a2) ''' [[1 1] [0 0]] [[1 0] [1 0]] '''
3.5,求矩陣對應列行的最大值,最小值,和。
計算每一列,行的和
from numpy import * '''計算每一列,行的和''' a1 = mat([[1,1],[2,3],[4,5]]) print(a1) # 列和,這裡得到的是1*2的矩陣 a2=a1.sum(axis=0) print(a2) ''' [[7 9]] ''' # 行和,這裡得到的是3*1的矩陣 a3=a1.sum(axis=1) print(a3) ''' [[2] [5] [9]] ''' # 計算第一行所有列的和,這裡得到的是一個數值 a4=sum(a1[1,:]) print(a4) ''' 5 '''
計算最大,最小值和索引
from numpy import * '''計算每一列,行的和''' a1 = mat([[1,1],[2,3],[4,5]]) print(a1) ''' [[1 1] [2 3] [4 5]] ''' # 計算a1矩陣中所有元素的最大值,這裡得到的結果是一個數值 maxa = a1.max() print(maxa) #5 # 計算第二列的最大值,這裡得到的是一個1*1的矩陣 a2=max(a1[:,1]) print(a2) #[[5]] # 計算第二行的最大值,這裡得到的是一個一個數值 maxt = a1[1,:].max() print(maxt) #3 # 計算所有列的最大值,這裡使用的是numpy中的max函式 maxrow = np.max(a1,0) print(maxrow) #[[4 5]] # ;//計算所有行的最大值,這裡得到是一個矩陣 maxcolumn = np.max(a1,1) print(maxcolumn) ''' [[1] [3] [5]] ''' # 計算所有列的最大值對應在該列中的索引 maxindex = np.argmax(a1,0) print(maxindex) #[[2 2]] # 計算第二行中最大值對應在改行的索引 tmaxindex = np.argmax(a1[1,:]) print(tmaxindex) # 1
3.6,矩陣的分隔和合並 (vstack hstack)
矩陣的分割,同列表和陣列的分割一致
from numpy import * ''' 矩陣的分隔,同列表和陣列的分隔一致''' a = mat(ones((3,3))) print(a) # 分隔出第二行以後的行和第二列以後的列的所有元素 b = a[1:,1:] print(b) ''' [[1. 1. 1.] [1. 1. 1.] [1. 1. 1.]] [[1. 1.] [1. 1.]] '''
矩陣的合併
from numpy import * a = mat(ones((2,2))) print(a) b = mat(eye(2)) print(b) # 按照列和並,即增加行數 c = vstack((a,b)) print(c) # 按照行合併,即行數不變,擴充套件列數 d = hstack((a,b)) print(d) ''' [[1. 1.] [1. 1.]] [[1. 0.] [0. 1.]] [[1. 1.] [1. 1.] [1. 0.] [0. 1.]] [[1. 1. 1. 0.] [1. 1. 0. 1.]] '''
3.7 陣列疊加合併
- 列合併/擴充套件:np.column_stack()
- 行合併/擴充套件:np.row_stack()
a = np.array((1,2,3,4)) b = np.array((11,22,33,44)) res1 = np.column_stack((a,b)) res2 = np.row_stack((a,b)) print(a) print(b) print(res1) print(res2) ''' [1 2 3 4] [11 22 33 44] [[ 1 11] [ 2 22] [ 3 33] [ 4 44]] [[ 1 2 3 4] [11 22 33 44]] '''
3.8 陣列均分(np.array.split())
直接看例子:
x = np.arange(10) res1 = np.array_split(x,2) res2 = np.array_split(x,3) print(res1) print(res2) ''' [array([0, 1, 2, 3, 4]), array([5, 6, 7, 8, 9])] [array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])] '''
3.9,矩陣,列表,陣列的轉換
列表可以修改,並且列表中元素可以使不同型別的資料,如下:
li =[[1],'hello',3]
numpy中陣列,同一個陣列中所有元素必須為同一個型別,有幾個常見的屬性:
from numpy import * a=array([[2],[1]]) print(a ) dimension=a.ndim m,n=a.shape # 元素總個數 number=a.size print(number) # 2 # 元素的型別 str=a.dtype print(str) # int32
numpy中的矩陣也有與陣列常見的幾個屬性,他們之間的轉換如下:
from numpy import * # 列表 a1 = [[1,2],[3,2],[5,2]] # 將列表轉化為二維陣列 a2 = array(a1) # 將列表轉化成矩陣 a3 = mat(a1) # 將矩陣轉化成陣列 a4 = array(a3) # 將矩陣轉換成列表 a5=a3.tolist() # 將陣列轉換成列表 a6=a2.tolist() print(type(a1)) print(type(a2)) print(type(a3)) print(type(a4)) print(type(a5)) print(type(a6)) ''' <class 'list'> <class 'numpy.ndarray'> <class 'numpy.matrixlib.defmatrix.matrix'> <class 'numpy.ndarray'> <class 'list'> <class 'list'> '''
注意:當列表為一維的時候,將他們轉換成陣列和矩陣後,再通過tolist()轉換成列表是不相同的,這裡需要做一些小小的修改,如下:
from numpy import * a1=[1,2,3] print(a1) print(type(a1)) a2=array(a1) print(a2) print(type(a2)) a3=mat(a1) print(a3) print(type(a3)) ''' [1, 2, 3] <class 'list'> [1 2 3] <class 'numpy.ndarray'> [[1 2 3]] <class 'numpy.matrixlib.defmatrix.matrix'> ''' a4=a2.tolist() print(a4) print(type(a4)) a5=a3.tolist() print(a5) print(type(a5)) ''' [1, 2, 3] <class 'list'> [[1, 2, 3]] <class 'list'> ''' a6=(a4 == a5) print(a6) print(type(a6)) a7=(a4 is a5[0]) print(a7) print(type(a7)) ''' False <class 'bool'> False <class 'bool'> '''
矩陣轉換成數值,存在以下一種情況:
from numpy import * dataMat=mat([1]) print(dataMat) print(type(dataMat)) ''' [[1]] <class 'numpy.matrixlib.defmatrix.matrix'> ''' # 這個時候獲取的就是矩陣的元素的數值,而不再是矩陣的型別 val=dataMat[0,0] print(val) print(type(val)) ''' 1 <class 'numpy.int32'> '''
4, matrix.getA()
getA()是numpy的一個函式,作用是將矩陣轉成一個ndarray,getA()函式和mat()函式的功能相反,是將一個矩陣轉化為陣列。
如果不轉,矩陣的每個元素將無法取出,會造成越界的問題,其具體解釋如下:
matrix.getA() Return self as an ndarray object. Equivalent to np.asarray(self) Parameters: None Returns: __ret_: ndarray self as an ndarray
舉例如下:
>>> x = np.matrix(np.arange(12).reshape((3,4))); x matrix([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) >>> x.getA() array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
那麼為什麼需要轉換呢?
因為在畫出資料集合的函式中,程式碼如下(取自機器學習實戰Logistic迴歸最佳擬合直線的函式)
def plotBestFit(weights): weights = weights.getA() ... for i in range(n): #分類 if int(labelMat[i]) == 1: xcord1.append(dataArr[i, 1]) ycord1.append(dataArr[i, 2]) else: xcord2.append(dataArr[i, 1]) ycord2.append(dataArr[i, 2])
在這個程式碼,我們需要取出其中每一行每一列的值
如果是矩陣的話,我們測試一下:
>>> b matrix([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]) >>> b[1][1] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "D:\Python\lib\site-packages\numpy\matrixlib\defmatrix.py", line 284, in __getitem__ out = N.ndarray.__getitem__(self, index) IndexError: index 1 is out of bounds for axis 0 with size 1 >>> >>> len(b[1]) 1 >>> len(b[1][0]) 1
可以發現我們取出矩陣的一行大小隻有1,如果你使用b[1][1],b[1][2]之類的就會越界
當我們轉為np.array型別時
>>> c array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]) >>> len(c[1]) 4 >>> c[1][1] 2 >>>
可以看出,我們可以取出任何一個值。
Python矩陣的切片
1,行操作
li = [[1,1],[1,3],[2,3],[4,4],[2,4]] from numpy import * a = [[1,2],[3,4],[5,6]] a = mat(a) # 列印整個矩陣 print(a[0:]) ''' [[1 2] [3 4] [5 6]] ''' # 列印矩陣E從1行開始到末尾行的內容 print(a[1:]) ''' [[3 4] [5 6]] ''' # 表示列印矩陣E 從1行到3行的內容 print(a[1:3]) ''' [[3 4] [5 6]] '''
2,列操作
li = [[1,1],[1,3],[2,3],[4,4],[2,4]] from numpy import * mat = mat(li) # 在整個矩陣的基礎下,列印1列(指的是序列為1的列 print(mat[:,0]) ''' [[1] [1] [2] [4] [2]] ''' # 在矩陣的1行到2行([1,3)) 的前提下列印兩列 # 2 列不是指兩列,而是序號為2的列 print(mat[1:3,1]) ''' [[3] [3]] '''
Python numpy庫其他函式用法
Numpy 的tile函式用法
tile函式位於Python模組numpy.lib.shape_base中,他的功能是重複某個陣列,比如 tile(A,reps),功能是將陣列A重複reps次,構成一個新的陣列。
1,函式的定義與說明
函式格式為 tile(A,reps)
A和reps 都是array_like
A的型別眾多,幾乎所有型別都可以:array list tuple dict matrix 以及基本資料型別Int string float 以及bool型別。
reps 的型別也很多,可以是tuple list dict array int bool 但不可以是float string matrix型別。
2,示例
>>> a = np.array([0, 1, 2]) >>> np.tile(a, 2) array([0, 1, 2, 0, 1, 2]) >>> np.tile(a, (2, 2)) array([[0, 1, 2, 0, 1, 2], [0, 1, 2, 0, 1, 2]]) >>> np.tile(a, (2, 1, 2)) array([[[0, 1, 2, 0, 1, 2]], [[0, 1, 2, 0, 1, 2]]]) >>> b = np.array([[1, 2], [3, 4]]) >>> np.tile(b, 2) array([[1, 2, 1, 2], [3, 4, 3, 4]]) >>> np.tile(b, (2, 1)) array([[1, 2], [3, 4], [1, 2], [3, 4]]) >>> c = np.array([1,2,3,4]) >>> np.tile(c,(4,1)) array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]])
from numpy import * code1 = tile(1,2) print(code1) # [1 1] code2 = tile((1,2,3),3) print(code2) # [1 2 3 1 2 3 1 2 3] a = [1,3,4] code3 = tile(a,[2,3]) print(code3) ''' [[1 3 4 1 3 4 1 3 4] [1 3 4 1 3 4 1 3 4]] '''
Numpy資料型別轉換astype dtype
1,檢視資料型別
In [11]: arr = np.array([1,2,3,4,5]) In [12]: arr Out[12]: array([1, 2, 3, 4, 5]) // 該命令檢視資料型別 In [13]: arr.dtype Out[13]: dtype('int64') In [14]: float_arr = arr.astype(np.float64) // 該命令檢視資料型別 In [15]: float_arr.dtype Out[15]: dtype('float64')
2,轉換資料型別
// 如果將浮點數轉換為整數,則小數部分會被截斷 In [7]: arr2 = np.array([1.1, 2.2, 3.3, 4.4, 5.3221]) In [8]: arr2 Out[8]: array([ 1.1 , 2.2 , 3.3 , 4.4 , 5.3221]) // 檢視當前資料型別 In [9]: arr2.dtype Out[9]: dtype('float64') // 轉換資料型別 float -> int In [10]: arr2.astype(np.int32) Out[10]: array([1, 2, 3, 4, 5], dtype=int32)
3,字串陣列轉換為數值型
In [4]: numeric_strings = np.array(['1.2','2.3','3.2141'], dtype=np.string_) In [5]: numeric_strings Out[5]: array(['1.2', '2.3', '3.2141'], dtype='|S6') // 此處寫的是float 而不是np.float64, Numpy很聰明,會將python型別對映到等價的dtype上 In [6]: numeric_strings.astype(float) Out[6]: array([ 1.2, 2.3, 3.2141])
Numpy 範數的用法
顧名思義,linalg = linear + algebralinalg = linear + algebra , norm則表示範數,首先需要注意的是範數是對向量(或者矩陣)的度量,是一個標量(scalar):
np.linalg.norm(求範數):linalg=linear(線性)+algebra(代數)
首先:help(np.linalg.norm) 檢視其文件:
norm(x, ord=None, axis=None, keepdims=False)
這裡我們只對常用設定進行說明,x表示要度量的向量,ord表示範數的種類,axis表示向量的計算方向,keepdims表示設定是否保持維度不變。
用法:
import numpy as np a=np.array([[complex(1,-1),3],[2,complex(1,1)]]) print(a) print(np.linalg.norm(a,ord=2) ) #計算矩陣2的範數 print(np.linalg.norm(a,ord=1) ) #計算矩陣1的範數 print(np.linalg.norm(a,ord=np.inf) ) #計算矩陣無窮的範數
示例:
import numpy as np x = np.array([5,7]) np.linalg.norm(x) 8.602325267042627 np.linalg.norm(x,ord=2) 8.602325267042627 np.linalg.norm(x,ord=1) 12.0 np.linalg.norm(x,ord=np.inf) 7.0
範數理論告訴我們,一範數 >= 二範數 >= 無窮範數
參考文獻:https://blog.csdn.net/taxueguilai1992/article/details/46581861
https://blog.csdn.net/lanchunhui/article/details/51004387