機器學習——科學計算庫numPy
什麼是numPy?用下面的圖來解釋一下:
如果一群人的特徵(如:年齡,性別,愛好等)構成了一個數據表,這個資料表是M * N的樣式,這就好比是一個M * N的矩陣。我們知道,矩陣的運算是很簡單的。把一些資料表示成矩陣的樣式對於計算機來說是很簡單的。並且效率也非常高。而numPy就是專門用來做矩陣運算的。當然不光是矩陣運算,還有其它的操作。
下面一 一舉例說明…
檔案讀取:
下面看一串程式碼:
import numpy as np #讀取檔案中的資料 txt=np.genfromtxt("Car Evaluation.csv",delimiter=",",dtype=str) print(type(txt)) print(txt)
輸出的結果:
可以看到,detail.txt中的資料確實被讀取出來了,以矩陣的形式返回。
如果不知道某個函式的用法,可以使用print(help(np.genfromtxt))
語句檢視。幫助中也提供了np.genfromtxt函式具體的例子:
矩陣定義:
程式碼:
#----------------矩陣定義----------------------- mat1=np.array([[1,2],[3,3],[1,2]]) mat2=np.array([[1,3]]) print("mat1:\n",mat1) print("mat2:\n",mat2) print("mat1維度:\n",mat1.shape) print("mat2維度:\n",mat2.shape)
執行結果:
用np.array()就可以定義一個矩陣。x.shape就表示x的維度,Python3中可以用mat1.shape顯示mat1矩陣的維度,結果是(3,2),表示mat1是一個3*2的矩陣。
注意:np.array([x,y,z])中的x,y,z必須是相同的結構。 如果有3個int型元素,一個float型元素。那麼3個int型元素都會變成float型元素。如下所示:
data=np.array([1,2,3,4])
print(data.dtype)
結果顯示為:
那結果變成這樣:
data=np.array([1,2,3,4.0]) print(data.dtype)
那結果變成這樣:
所以說,np.array([x,y,z])中的x,y,z必須是相同的結構,這是一個潛在的規則。
取值:
如果有一堆陣列,我想從裡面去除某一個數字,那麼用下面的程式碼就可以實現:
#找出txt文字的維度,尋找第1728行第6列的值,因為矩陣是從(0,0)開始的相當於從座標原點開始,所以程式碼使用cut_data=txt[1727,5]
print(txt.shape)
cut_data=txt[1727,5]
print("第1728行第6列的值是:",cut_data)
輸出結果:
切片:
Python中可以直接對List陣列進行切片,在numPy中也可以。
vector1=np.array([1,2,3,4])
print(vector1[:3])
print("-----------")
vector2=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
print(vector2[:,0:2]) #取所有行,第0-1列
print("-----------")
print(vector2[1:3,0:2])
執行結果:
判斷:
在numPy中,可以直接對List陣列或矩陣進行元素判斷,而不需要直接使用for迴圈去遍歷查詢。
data1=np.array([1,2,3,4,5])
data2=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
print("判斷data1中是否包含10:\n",data1==10)
print("判斷data1中是否包含5:\n",data1==5)
print("判斷data2中是否包含20:\n",data2==20)
執行結果:
可以看到,當被查詢的元素存在時,會返回True這個布林型別,否則返回False。
當然,這個bool型別也可以當成一個索引。
#bool型別也可以當成索引
data1=np.array([1,2,3,4,5])
a=(data1==5)
print(data1[a])
執行結果:
當我輸入的為:a=(data1==6) print(data1[a])
時,結果返回為空,因為用該索引查詢不到對應的元素。
執行結果:
對於二維矩陣也是一樣的:
data1=np.array([1,2,3,4,5])
data2=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
print("判斷data1中是否包含10:\n",data1==10)
print("判斷data1中是否包含5:\n",data1==5)
print("判斷data2中是否包含20:\n",data2==20)
#bool型別也可以當成索引
#在矩陣第二列找出對應元素
a=(data2[:,1]==50)
#用索引在該行找出所在的行
print(data2[a,:])
執行結果:
除了單個元素查詢,還能多個元素查詢。那麼查詢的結果是怎麼樣的呢?
data1=np.array([1,2,3,4,5])
data2=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
equal10_15=(data2==10)&(data2==15)#與操作,同時滿足這兩個條件
print(equal10_15)
輸出結果:
可以看到,並沒有一個同時滿足既是10又是15的元素。
換一下或操作:
data1=np.array([1,2,3,4,5])
data2=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
equal10_15=(data2==10)|(data2==20)
print(equal10_15)
執行結果:
可以看到,找到了同時滿足既是10又是20的元素。
資料型別轉換
有一個數組為[‘1’,‘2’,‘3’,‘4’],現在想要將它轉換成float型別的,就進行如下操作:
list=np.array(['1','2','3','4'])
print("list的資料型別是:\n",list.dtype)
print(list)
list_as=list.astype(float) #astype()是一個型別轉換函式
print("list_as的資料型別是:\n",list_as.dtype)
print(list_as)
執行結果:
求最小最大值
numPy中也可以求矩陣中的最小和最大值:
Mat_data=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
min_mat=Mat_data.min() #內建函式
max_mat=Mat_data.max()
print("矩陣中最小元素:\n",min_mat)
print("矩陣中最大元素:\n",max_mat)
# print(help(np.array))
執行結果:
行列求和
numPy還可以對矩陣的每行和每列分別求和:
Mat_data=np.array([[10,20,30],
[40,50,60],
[70,80,90]])
add1=Mat_data.sum(axis=1) #axis=1,矩陣每行進行求和
print("矩陣每行進行求和:\n",add1)
add2=Mat_data.sum(axis=0) #axis=0,矩陣每列進行求和
print("矩陣每列進行求和:\n",add2)
執行結果:
函式計算
numPy中還可以對矩陣各元素進行函式操作。
x=np.arange(3)
print(x)
print(np.exp(x))#e的n次方
print(np.sqrt(x))#開根號
執行結果:
矩陣變向量
把M*N的矩陣通過函式變成一個單行向量,也可以把單行向量變成二維矩陣。
a=np.array([[1,2,3],#2*3矩陣
[2,3,4]])
b=a.ravel()#變成一行的向量
print(b)
c=b.reshape(3,2)#變成3*2的矩陣,reshape(3,-1)自動計算每行有幾個
print(c)
print(c.T) #求轉置矩陣,行列互換
執行結果:
矩陣拼接
把兩個或多個矩陣按行或按列進行拼接起來。
a=np.array([[1,2],#2*3矩陣
[2,3]])
b=np.array([[2,1],#2*3矩陣
[0,0]])
c=np.vstack((a,b)) #豎著拼接
d=np.hstack((a,b)) #橫著拼接
print(c)
print("-----------------")
print(d)
執行結果:
矩陣拆分
a=np.floor(10*np.random.random((2,12))) #向下取整定義一個2*12的隨機矩陣
print(a)
print("--------------------------")
print(np.hsplit(a,3)) #豎著切
print("--------------------------")
print(np.vsplit(a,2)) #橫著切
執行結果:
複製
a=np.arange(8)
print(a)
b=a
b.shape=(2,4) #改變b的維度
print("b.shape:\n",b.shape)
print("a.shape:\n",a.shape)
print("id(a):",id(a))
print("id(b):",id(b))
執行結果:
也就是說,改變了b的維度,a也會發生變化。再看id,兩個id的值都是一樣的。所以說,a與b只是名字上的不同,就像別人叫你綽號一樣,你還是你。
淺複製
a=np.arange(8)
c=a.view() #淺複製
c.shape=(4,2)
print("c.shape:\n",c.shape)
print("a.shape:\n",a.shape)
c[0,0]=100
print("c:",c)
print("a:",a)
執行結果:
可以看到,通過view()複製之後的c,改變維度,但是a的維度依然不會變。但是,改變c中某一元素的值,a中的值卻變了。並且兩個矩陣的id也不同。所以說,雖然兩個矩陣沒有什麼共同聯絡,但是卻共用著同一組資料。
分離複製
這個意思就是說複製出來的矩陣完全是獨立的,你是你,他是他。
d=a.copy()
d.shape=(3,4)
a.shape=(4,3)
d[0,0]=999
print("d.shape:\n",d.shape)
print("a.shape:\n",a.shape)
print("d:",d)
print("a:",a)
print("id(d):",id(d))
print("id(a):",id(a))
執行結果:
最值
我們也可以查詢矩陣中每一行或每一列的最大值或最小值。
a=np.array([[1,5],
[3,4],
[1,2]])
b=a.argmax(axis=0) #取每一列的最大值,這裡輸出的是索引
print("索引值:\n",b)
print("每列最大值:\n",a[b,range(a.shape[1])]) #列印輸出的最值
執行結果:
矩陣擴充套件
a=np.arange(0,30,10) #0-30,步長為10的行向量
b=np.tile(a,(2,2)) #將a擴充套件成2*2的矩陣,行列均變成原來的2倍
c=np.tile(a,(3,5)) #將a擴充套件成3*5的矩陣,行變成原來的3倍,列變成原來的5倍
print("a:\n",a)
print("b:\n",b)
print("c:\n",c)
執行結果:
排序
numPy也能對矩陣中的元素按行或列進行排序。
a=np.array([[2,3,1],
[4,0,2]])
b=np.sort(a,axis=1) #按列進行排序
print("按列進行排序(b):\n",b)
c=np.array([3,2,4,0])
c_arg=np.argsort(c) #預設降序排序
print("降序索引:\n",c_arg)
print("降序排序:\n",c[c_arg])
執行結果:
這裡放下本章所講的所有原始碼:
(需要哪章將註釋去掉即可)
import numpy as np
#-----------讀取檔案中的資料-------------
# txt=np.genfromtxt("Car Evaluation.csv",delimiter=",",dtype=str)
#
# print(type(txt))
# print(txt)
# print(help(np.genfromtxt))
#----------------矩陣定義-----------------------
# mat1=np.array([[1,2],[3,3],[1,2]])
# mat2=np.array([[1,3]])
# print("mat1:\n",mat1)
# print("mat2:\n",mat2)
# print("mat1維度:\n",mat1.shape)
# print("mat2維度:\n",mat2.shape)
#---------------取值----------------------------
#找出txt文字的維度,尋找第1728行第6列的值,因為矩陣是從(0,0)開始的相當於從座標原點開始,所以程式碼使用cut_data=txt[1727,5]
# print(txt.shape)
# cut_data=txt[1727,5]
# print("第1728行第6列的值是:",cut_data)
#----------------切片-----------------------------
#[0:2]這是一個左閉右開的範圍
# vector1=np.array([1,2,3,4])
# print(vector1[:3])
# print("-----------")
# vector2=np.array([[1,2,3],
# [4,5,6],
# [7,8,9]])
# print(vector2[:,0:2]) #取所有行,第0-1列
# print("-----------")
# print(vector2[1:3,0:2])
#--------------------判斷----------------------------
#
# data1=np.array([1,2,3,4,5])
# data2=np.array([[10,20,30],
# [40,50,60],
# [70,80,90]])
# print("判斷data1中是否包含10:\n",data1==10)
# print("判斷data1中是否包含5:\n",data1==5)
# print("判斷data2中是否包含20:\n",data2==20)
# #bool型別也可以當成索引
# #在矩陣第二列找出對應元素
# a=(data2[:,1]==50)
# #用索引在該行找出所在的行
# print(data2[a,:])
# #與-或判斷
# equal10_15=(data2==10)|(data2==20)
# print(equal10_15)
#------------------資料型別轉換-------------------------
# list=np.array(['1','2','3','4'])
# print("list的資料型別是:\n",list.dtype)
# print(list)
#
# list_as=list.astype(float) #astype()是一個型別轉換函式
# print("list_as的資料型別是:\n",list_as.dtype)
# print(list_as)
#----------------求最小最大值-------------------------
# Mat_data=np.array([[10,20,30],
# [40,50,60],
# [70,80,90]])
# min_mat=Mat_data.min() #內建函式
# max_mat=Mat_data.max()
# print("矩陣中最小元素:\n",min_mat)
# print("矩陣中最大元素:\n",max_mat)
# # print(help(np.array))
#--------------行列求和-----------------------------
# Mat_data=np.array([[10,20,30],
# [40,50,60],
# [70,80,90]])
#
# add1=Mat_data.sum(axis=1) #axis=1,矩陣每行進行求和
# print("矩陣每行進行求和:\n",add1)
# add2=Mat_data.sum(axis=0) #axis=0,矩陣每列進行求和
# print("矩陣每列進行求和:\n",add2)
#---------------函式計算--------------------------
# x=np.arange(3)
# print(x)
# print(np.exp(x))#e的n次方
# print(np.sqrt(x))#開根號
#--------------------矩陣變向量操作-----------------
# a=np.array([[1,2,3],#2*3矩陣
# [2,3,4]])
# b=a.ravel()#變成一行的向量
# print(b)
# c=b.reshape(3,2)#變成3*2的矩陣,reshape(3,-1)自動計算每行有幾個
# print(c)
# print(c.T) #求轉置矩陣,行列互換
#--------------------矩陣拼接操作-----------------
# a=np.array([[1,2],#2*3矩陣
# [2,3]])
# b=np.array([[2,1],#2*3矩陣
# [0,0]])
# c=np.vstack((a,b)) #豎著拼接
# d=np.hstack((a,b)) #橫著拼接
# print(c)
# print("-----------------")
# print(d)
#------------------矩陣拆分-----------------------
# a=np.floor(10*np.random.random((2,12))) #向下取整定義一個2*12的隨機矩陣
# print(a)
# print("--------------------------")
# print(np.hsplit(a,3)) #豎著切
# print("--------------------------")
# print(np.vsplit(a,2)) #橫著切
#--------------------複製-------------------------
# a=np.arange(12)
# # print(a)
# # b=a
# # b.shape=(2,4) #改變b的維度
# # print("b.shape:\n",b.shape)
# # print("a.shape:\n",a.shape)
# # print("id(a):",id(a))
# # print("id(b):",id(b))
# #
#---------------------淺複製--------------------
# a=np.arange(8)
# # c=a.view()
# # c.shape=(4,2)
# # print("c.shape:\n",c.shape)
# # print("a.shape:\n",a.shape)
# # c[0,0]=100
# # print("c:",c)
# # print("a:",a)
# # print("id(c):",id(c))
# # print("id(a):",id(a))
#------------------分離複製---------------------
# a=np.arange(12)
# d=a.copy()
# d.shape=(3,4)
# a.shape=(4,3)
# d[0,0]=999
# print("d.shape:\n",d.shape)
# print("a.shape:\n",a.shape)
# print("d:",d)
# print("a:",a)
# print("id(d):",id(d))
# print("id(a):",id(a))
#------------------取最值---------------------
# a=np.array([[1,5],
# [3,4],
# [1,2]])
# b=a.argmax(axis=0) #取每一列的最大值,這裡輸出的是索引
# print("索引值:\n",b)
# print("每列最大值:\n",a[b,range(a.shape[1])]) #列印輸出的最值
#--------------------矩陣擴充套件-----------------
# a=np.arange(0,30,10) #0-30,步長為10的行向量
# b=np.tile(a,(2,2)) #將a擴充套件成2*2的矩陣,行列均變成原來的2倍
# c=np.tile(a,(3,5)) #將a擴充套件成3*5的矩陣,行變成原來的3倍,列變成原來的5倍
# print("a:\n",a)
# print("b:\n",b)
# print("c:\n",c)
#----------------------排序-----------------------
# a=np.array([[2,3,1],
# [4,0,2]])
# b=np.sort(a,axis=1) #按列進行排序
# print("按列進行排序(b):\n",b)
#
#
# c=np.array([3,2,4,0])
# c_arg=np.argsort(c) #預設降序排序
# print("降序索引:\n",c_arg)
# print("降序排序:\n",c[c_arg])