1. 程式人生 > >機器學習——科學計算庫numPy

機器學習——科學計算庫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])