重磅干貨,第一時間送達(dá)
來源:大數(shù)據(jù)
Numpy提供的主要功能具體如下:
ndarray——一個具有向量算術(shù)運(yùn)算和復(fù)雜廣播能力的多維數(shù)組對象。
用于對數(shù)組數(shù)據(jù)進(jìn)行快速運(yùn)算的標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)。
用于讀寫磁盤數(shù)據(jù)的工具以及用于操作內(nèi)存映射文件的工具。
非常有用的線性代數(shù),傅里葉變換和隨機(jī)數(shù)操作。
用于集成C /C++和Fortran代碼的工具。
除了明顯的科學(xué)計算用途之外,Numpy還可以用作通用數(shù)據(jù)的高效多維容器,定義任意的數(shù)據(jù)類型。這些都使得Numpy能夠無縫、快速地與各種數(shù)據(jù)庫集成。
提示:這里提到的“廣播”可以這么理解:當(dāng)兩個維度不同的數(shù)組(array)運(yùn)算的時候,可以將低維的數(shù)組復(fù)制成高維數(shù)組參與運(yùn)算(因為Numpy運(yùn)算的時候需要結(jié)構(gòu)相同)。
在學(xué)習(xí)圖像識別的過程中,需要將圖片轉(zhuǎn)換為矩陣。即將對圖片的處理簡化為向量空間中的向量運(yùn)算?;谙蛄窟\(yùn)算,我們就可以實現(xiàn)圖像的識別。
01 創(chuàng)建數(shù)組
現(xiàn)在就來關(guān)注下Numpy中的一些核心知識點(diǎn)。在Numpy中,最核心的數(shù)據(jù)結(jié)構(gòu)是ndarray, ndarray代表的是多維數(shù)組,數(shù)組指的是數(shù)據(jù)的集合。為了方便理解,我們下面列舉一個小例子。
一個班級里學(xué)生的學(xué)號可以通過一維數(shù)組來表示,數(shù)組名為a,數(shù)組a中存儲的是數(shù)值類型的數(shù)據(jù),分別是1,2,3,4。
索引 | 學(xué)號 |
0 | 1 |
1 | 2 |
2 | 3 |
3 | 4 |
其中,a[0]代表的是第一個學(xué)生的學(xué)號1,a[1]代表的是第二個學(xué)生的學(xué)號2,以此類推。
一個班級里學(xué)生的學(xué)號和姓名,可以用二維數(shù)組來表示,數(shù)組名為b。
1 | Tim |
2 | Joey |
3 | Johnny |
4 | Frank |
類似的,其中b[0,0]代表的就是1(學(xué)號),b[0,1]代表的就是Tim(學(xué)號為1的學(xué)生的名字),以此類推b[1,0]代表的是2(學(xué)號)等。
借用線性代數(shù)的說法,一維數(shù)組通常稱為向量(vector),二維數(shù)組通常稱為矩陣(matrix)。
當(dāng)我們安裝完Anaconda之后,默認(rèn)情況下Numpy已經(jīng)在庫中了,所以不需要額外安裝。下面我們來寫一些語句簡單測試下Numpy庫。
1)在Anaconda的Notebook里輸入
import numpy as np
之后,通過鍵盤按住Shift+Enter執(zhí)行,如果沒有報錯,則說明Numpy已被正常引入,如圖2-7所示。
▲圖2-7 在Notebook中引入Numpy
稍微解釋下這條語句:通過import關(guān)鍵字將Numpy庫引入,然后通過as為其取一個別名np,別名的作用是為了便于后續(xù)引用。
2)Numpy中的array()可以直接導(dǎo)入向量,代碼如下:
vector = np.array([1,2,3,4])
3)numpy.array()方法也可以導(dǎo)入矩陣,代碼如下:
matrix = np.array([[1,'Tim'],[2,'Joey'],[3,'Johnny'],[4,'Frank']])
02 創(chuàng)建Numpy數(shù)組
我們可以通過創(chuàng)建Python列表(list)的方式來創(chuàng)建Numpy矩陣,比如輸入
nparray = np.array([i for i in range(10)])
可以看到返回的結(jié)果是
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
同樣,也可以通過Python列表的方式來修改值,比如輸入
nparray[0] = 10
再來觀察nparray的向量內(nèi)容就會發(fā)現(xiàn)返回的結(jié)果是
array([ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Numpy數(shù)組還封裝了其他方法來創(chuàng)建矩陣。首先,我們介紹第一個方法np.zeros(從命名規(guī)則來看,這個方法就是用來創(chuàng)建數(shù)值都為0的向量),比如,我們輸入:
a = np.zeros(10)
可以看到結(jié)果為:
array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
從上述結(jié)果可以看出,每一個0后面都有一個小數(shù)點(diǎn),調(diào)用a.dtype會發(fā)現(xiàn)我們創(chuàng)建的這個向量的類型為dtype(‘float64’)。值得注意的是:在大部分圖像識別算法開發(fā)中,我們使用的都是float64這個類型。如果希望在創(chuàng)建Numpy矩陣的時候強(qiáng)制規(guī)定一種類型,那么我們可以使用以下代碼:
np.zeros(10,dtype=int)
這樣,返回的結(jié)果在矩陣中的數(shù)據(jù)就都是整型0了。介紹完使用zeros方法創(chuàng)建向量之后,再來看看如何創(chuàng)建一個多維矩陣。我們可以使用傳入元組的方式,代碼如下:
np.zeros(shape=(3,4)) #代表創(chuàng)建的是三行四列的矩陣并且其數(shù)據(jù)類型為float64
返回的結(jié)果為:
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
與np.zeros方法相似的還有np.ones方法,顧名思義,np.ones方法創(chuàng)建的矩陣的數(shù)值都為1。我們來舉個例子:
np.ones((3,4))
返回的結(jié)果如下:
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
讀者可能會比較好奇,既然我們可以創(chuàng)建數(shù)值全為0的矩陣,也可以創(chuàng)建數(shù)值全為1的矩陣,那么Numpy是否提供了一個方法可以讓我們自己指定值呢?答案是肯定的,這個方法就是np.full方法,我們來看一個例子,代碼如下:
np.full((3,5),121) #這個方法的意思是我們創(chuàng)建了一個三行五列的矩陣,默認(rèn)值為121
返回的結(jié)果是:
array([[121, 121, 121, 121, 121],
[121, 121, 121, 121, 121],
[121, 121, 121, 121, 121]])
我們也可以使用np.arange方法來創(chuàng)建Numpy的矩陣。示例代碼如下:
np.arange(0,20,2) #arange接收三個參數(shù),與Python中的range方法相似,arange也是前閉后開的方法,第一個參數(shù)為向量的第一個值0,第二個參數(shù)為最后一個值20,因為是后開所以取的是18,第三個參數(shù)為步長,默認(rèn)為1,本例中設(shè)置為2,所以最后一個值是18。
返回的結(jié)果是:
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
我們可以使用np.linspace方法(前閉后閉)來對Numpy矩陣進(jìn)行等分,比如將0~10等分為5份的代碼如下:
np.linspace(0,10,5)
返回的結(jié)果是:
array([ 0. , 2.5, 5. , 7.5, 10. ])
下面通過幾個例子再來看看在Numpy矩陣中如何生成隨機(jī)數(shù)矩陣。
1)生成一個長度為10的向量,里面每一個數(shù)值都是介于0~10之間的整數(shù),代碼如下:
import numpy as np
np.random.randint(0,10,10)
2)如果不確定每個參數(shù)代表的意思,則加上參數(shù)名size,代碼如下:
np.random.randint(0,5,size=5) #注意是前閉后開,永遠(yuǎn)取不到5
3)我們也可以生成一個三行五列的整數(shù)矩陣,代碼如下
np.random.randint(4,9,size=(3,5))
4)seed的作用:如果不希望每次生成的隨機(jī)數(shù)都不固定,那么我們可以使用np.random.seed(1),隨機(jī)種子使用數(shù)字1記錄,這以后只要是用隨機(jī)種子1生成的隨機(jī)數(shù)就都是固定的。
5)我們也可以生成介于0~1之間的浮點(diǎn)數(shù)的向量或者矩陣,代碼如下:
np.random.random(10) #生成0~1之間的浮點(diǎn)數(shù),向量的長度為10
np.random.random((2,4)) #生成0~1之間的浮點(diǎn)數(shù),二行四列的矩陣
6)np.random.normal()表示的是一個正態(tài)分布,normal在這里是正態(tài)的意思。numpy.random.normal(loc=0,scale=1,size=shape)的意義如下:
參數(shù)loc(float):正態(tài)分布的均值,對應(yīng)這個分布的中心。loc=0說明這是一個以Y軸為對稱軸的正態(tài)分布。
參數(shù)scale(float):正態(tài)分布的標(biāo)準(zhǔn)差,對應(yīng)分布的寬度,scale越大,正態(tài)分布的曲線越矮胖,scale越小,曲線越高瘦。
參數(shù)size(int或者整數(shù)元組):輸出的值賦在shape里,默認(rèn)為None。
03 獲取Numpy屬性
首先,我們通過Numpy中的一個方法arange(n),生成0到n-1的數(shù)組。比如,我們輸入
np.arange(15)
可以看到返回的結(jié)果是
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
然后,再通過Numpy中的reshape(row,column)方法,自動構(gòu)架一個多行多列的array對象。
比如,我們輸入:
a = np.arange(15).reshape(3,5) #代表3行5列
可以看到結(jié)果:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
有了基本數(shù)據(jù)之后,我們就可以通過Numpy提供的shape屬性獲取Numpy數(shù)組的行數(shù)與列數(shù),示例代碼如下:
print(a.shape)
可以看到返回的結(jié)果是一個元組(tuple),第一個3代表的是3行,第二個5代表的是5列:
(3, 5)
我們可以通過.ndim來獲取Numpy數(shù)組的維度,示例代碼如下:
importnumpy as np
x = np.arange(15)
print(x.ndim) #輸出x向量的維度,這時能看到的維度是1維
X = x.reshape(3,5) #將x向量轉(zhuǎn)為三行五列的二維矩陣
Print(X.ndim) #輸出X矩陣的維度,這時能看到的維度是2維
reshape方法的特別用法
如果只關(guān)心需要多少行或者多少列,其他由計算機(jī)自己來算,那么這個時候我們可以使用如下方法:
x.reshape(15,-1) #我關(guān)心的是我只要15行,列由計算機(jī)自己來算
x.reshape(-1,15) #我關(guān)心的是我只要15列,行由計算機(jī)自己來算
04 Numpy數(shù)組索引
Numpy支持類似list的定位操作,示例代碼如下:
import numpy as np
matrix = np.array([[1,2,3],[20,30,40]])
print(matrix[0,1])
得到的結(jié)果是2。
上述代碼中的matrix[0,1],0代表的是行,在Numpy中,0代表起始的第一個,所以取的是第1行,之后的1代表的是列,所以取的是第2列。那么,最后的輸出結(jié)果是取第一行第二列,也就是2這個值了。
05 切片
Numpy支持類似list的切片操作,示例代碼如下:
import numpy as np
matrix = np.array([
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
])
print(matrix[:,1])
print(matrix[:,0:2])
print(matrix[1:3,:])
print(matrix[1:3,0:2])
上述的代碼中
print(matrix[:,1])語法代表選擇所有的行,而且列的索引是1的數(shù)據(jù),因此返回的結(jié)果是10,25,40。
print(matrix[:,0:2])代表的是選取所有的行,而且列的索引是0和1的數(shù)據(jù)。
print(matrix[1:3,:])代表的是選取所有的列,而且行的索引值是1和2的數(shù)據(jù)。
print(matrix[1:3,0:2])代表的是選取行的索引是1和2,而且列的索引是0和1的所有數(shù)據(jù)。
06 Numpy中的矩陣運(yùn)算
矩陣運(yùn)算(加、減、乘、除),在本書中將嚴(yán)格按照數(shù)學(xué)公式來進(jìn)行演示,即兩個矩陣的基本運(yùn)算必須具有相同的行數(shù)與列數(shù)。本例只演示兩個矩陣相減的操作,其他的操作讀者可以自行測試。示例代碼如下:
import numpy as np
myones = np.ones([3,3])
myeye = np.eye(3) #生成一個對角線的值為1,其余值都為0的三行三列矩陣
print(myeye)
print(myones-myeye)
輸出結(jié)果如下:
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
[[ 0. 1. 1.]
[ 1. 0. 1.]
[ 1. 1. 0.]]
提示:numpy.eye(N, M=None, k=0, dtype=<type 'float'>)中第一個參數(shù)輸出矩陣(行數(shù)=列數(shù)),第三個參數(shù)默認(rèn)情況下輸出的是對角線的值全為1,其余值全為0。
除此之外,Numpy還預(yù)置了很多函數(shù),使用這些函數(shù)可以作用于矩陣中的每個元素。
Numpy預(yù)置函數(shù)及說明:
np.sin(a):對矩陣a中的每個元素取正弦,sin(x)
np.cos(a):對矩陣a中的每個元素取余弦,cos(x)
np.tan(a):對矩陣a中的每個元素取正切,tan(x)
np.sqrt(a):對矩陣a中的每個元素開根號
np.abs(a):對矩陣a中的每個元素取絕對值
1. 矩陣之間的點(diǎn)乘
矩陣真正的乘法必須滿足第一個矩陣的列數(shù)等于第二個矩陣的行數(shù),矩陣乘法的函數(shù)為dot。示例代碼如下:
import numpy as np
mymatrix = np.array([[1,2,3],[4,5,6]])
a = np.array([[1,2],[3,4],[5,6]])
print(mymatrix.shape[1] == a.shape[0])
print(mymatrix.dot(a))
其輸出結(jié)果如下:
[[22 28]
[49 64]]
上述示例代碼的原理是將mymatrix的第一行[1,2,3]與a矩陣的第一列[1,3,5]相乘然后相加,接著將mymatrix的第一行[1,2,3]與a矩陣的第二列[2,4,6]相乘然后相加,以此類推。
2. 矩陣的轉(zhuǎn)置
矩陣的轉(zhuǎn)置是指將原來矩陣中的行變?yōu)榱?。示例代碼如下:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(a.T)
輸出結(jié)果如下:
[[1 4]
[2 5]
[3 6]]
3. 矩陣的逆
需要首先導(dǎo)入numpy.linalg,再用linalg的inv函數(shù)來求逆,矩陣求逆的條件是矩陣的行數(shù)和列數(shù)必須是相同的。示例代碼如下:
import numpy as np
import numpy.linalg as lg
A = np.array([[0,1],[2,3]])
invA = lg.inv(A)
print(invA)
print(A.dot(invA))
輸出結(jié)果如下:
[[-1.5 0.5]
[ 1. 0. ]]
逆矩陣就是,原矩陣A.dot(invA)以及逆矩陣invA.dot(A)的結(jié)果都為單位矩陣。并不是所有的矩陣都有逆矩陣。
07 數(shù)據(jù)類型轉(zhuǎn)換
Numpy ndarray數(shù)據(jù)類型可以通過參數(shù)dtype進(jìn)行設(shè)定,而且還可以使用參數(shù)astype來轉(zhuǎn)換類型,在處理文件時該參數(shù)會很實用。注意,astype調(diào)用會返回一個新的數(shù)組,也就是原始數(shù)據(jù)的備份。
比如,將String轉(zhuǎn)換成float。示例代碼如下:
vector = numpy.array(['1', '2', '3'])
vector = vector.astype(float)
注意:在上述例子中,如果字符串中包含非數(shù)字類型,那么從string轉(zhuǎn)換成float就會報錯。
聯(lián)系客服