numpy(numerical python)是一個(gè)開(kāi)源的 Python 科學(xué)計(jì)算庫(kù)担映,支持大量的數(shù)組與矩陣運(yùn)算持痰,并為其提供了大量的數(shù)學(xué)函數(shù)修陡。numpy 是用 C 語(yǔ)言開(kāi)發(fā)的姓赤,比 Python 的自帶數(shù)據(jù)結(jié)構(gòu) Tuple赡译、List、Dictionary 和 Set 都要快不铆。另外 numpy 是屬于 Python 的擴(kuò)展程序庫(kù)蝌焚,也即是第三方庫(kù),所以以前沒(méi)有安裝 numpy 庫(kù)的小伙伴們需要先安裝 numpy誓斥。由于 numpy 庫(kù)是一個(gè)科學(xué)計(jì)算庫(kù)只洒,所以在本篇我們將采用 Anaconda 中自帶的 jupyter notebook 來(lái)給小伙伴們演示 numpy 的各種方法。如果有不了解 Anaconda 的小伙伴劳坑,可以先了解一下:http://www.reibang.com/p/68f0565c7036
首先定義一個(gè)二維列表 arr
(類(lèi)型為L(zhǎng)ist[List[int]])毕谴,然后通過(guò) numpy 的 np.array
方法將 Python 列表 arr
轉(zhuǎn)成 numpy 中的數(shù)組 arr1
(類(lèi)型為ndarray):
In [1]: import numpy as np
arr = [[1,2,3],[2,3,4]]
arr1 = np.array(arr)
arr1
Out [1]: array([[1, 2, 3],
[2, 3, 4]])
接著我們調(diào)用 size
函數(shù)查看 arr1
元素的個(gè)數(shù):
In [2]: print(arr1.size)
Out [2]: 6
然后我們可以通過(guò) shape
函數(shù)查看 arr1
的形狀:
In [3]: print(arr1.shape)
Out [3]: (2, 3)
我們可以將 List 轉(zhuǎn)成 ndarray,并指定 ndarray 元素的類(lèi)型為 int:
In [4]: a = np.array([2,42,11,3],dtype=np.int)
print(a.dtype)
Out [4]: int64
同樣地距芬,我們也可以指定 ndarray元素類(lèi)型為 float:
In [5]: a = np.array([2,42,11,3],dtype=np.float)
print(a.dtype)
Out [5]: float64
我們可以通過(guò) zeros
函數(shù)填充一個(gè)3行4列的矩陣:
In [6]: a = np.zeros((3,4))
print(a)
Out [6]: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
常用的還有使用 ones
函數(shù)填充矩陣:
In [7]: a = np.ones((3,2),dtype=int)
print(a)
Out [7]: [[1 1]
[1 1]
[1 1]]
使用 arange
函數(shù)生成一個(gè)10到20的數(shù)組涝开,步長(zhǎng)為2:
In [8]: a = np.arange(10,20,2)
print(a)
Out [8]: [10 12 14 16 18]
也可以使用 reshape
函數(shù)對(duì) arange
生成的數(shù)組重新定義形狀:
In [9]: a = np.arange(12).reshape((3,4)) # np.arange(12) 表示生成一個(gè)從0到11的數(shù)組,共12個(gè)值框仔,步長(zhǎng)默認(rèn)為1
print(a)
Out [9]: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
通過(guò) linspace
函數(shù)可以切分?jǐn)?shù)據(jù):
In [10]: a = np.linspace(1,10,5) #從1到10舀武,切成5個(gè)段(區(qū)間)
print(a)
Out [10]: [ 1. 3.25 5.5 7.75 10. ]
對(duì)數(shù)組按照元素進(jìn)行 加減乘除:
In [11]: a = np.array([10,20,30,40])
b = np.array([1,2,3,4])
c = np.arange(4) #不包括4,從0 到 3 共4個(gè)元素
print(a-b) #兩個(gè)數(shù)組中每個(gè)元素相減
print(b+c) #兩個(gè)數(shù)組中每個(gè)元素相加
print(b**2) #數(shù)組b的平方
print(a*b) # 兩個(gè)數(shù)組相乘
Out [11]: [ 9 18 27 36]
[1 3 5 7]
[ 1 4 9 16]
[ 10 40 90 160]
random
函數(shù)可以生成0-1之間的隨機(jī)數(shù)值:
In [12]: a = np.random.random((2,4)) #2行4列的隨機(jī)數(shù)(0-1)之間
print(a)
Out [12]: [[0.97164977 0.14426644 0.36158434 0.17456143]
[0.04331342 0.18312231 0.2126627 0.17222228]]
我們可以通過(guò) sum
函數(shù)离斩、min
函數(shù)和 max
函數(shù)分別得到數(shù)組的各個(gè)元素的和银舱,最小值和最大值:
In [13]: print(np.sum(a)) #a的元素之和
print(np.min(a)) #a的最小值
print(np.max(a)) #a的最大值
Out [13]: 2.2633826930383676
0.043313416357604995
0.9716497706841624
另外,如果聲明了 axis
參數(shù)跛梗,可以對(duì)數(shù)組的行或者列進(jìn)行統(tǒng)計(jì):
In [14]: print(np.sum(a,axis=1)) # axis=1代表行
print(np.sum(a,axis=0)) # axis=0代表列
Out [14]: [1.65206198 0.61132071]
[1.01496319 0.32738875 0.57424704 0.34678372]
當(dāng)然寻馏,也可以用 argmin
函數(shù)和 argmax
函數(shù)分別得到數(shù)組中最小值的索引和最大值的索引:
In [15]: print(np.argmin(a)) #該矩陣最小值的索引
print(np.argmax(a)) #該矩陣最大值的索引
Out [15]: 4
0
如果想輸出數(shù)組中所有非0元素的角標(biāo),可以用 nonzero
函數(shù):
In [16]: print(np.nonzero(a)) #輸出所有非0元素的角標(biāo)
Out [16]: (array([0, 0, 0, 0, 1, 1, 1, 1]), array([0, 1, 2, 3, 0, 1, 2, 3]))
注核偿,第一個(gè)數(shù)組代表行號(hào)诚欠,第二個(gè)數(shù)組代表列號(hào)
arange
函數(shù)也能生成一個(gè)倒序數(shù)值的數(shù)組:
In [17]: a = np.arange(11,-1,-1).reshape((3,4)) #arange包括第一個(gè)值,不包括第二個(gè)值的區(qū)間,11- -1 是從11到0轰绵,-1代表遞減
print(a)
Out [17]: [[11 10 9 8]
[ 7 6 5 4]
[ 3 2 1 0]]
可以用 sort
函數(shù)對(duì)矩陣的每一行獨(dú)立排序:
In [18]: print(np.sort(a))
Out [18]: [[ 8 9 10 11]
[ 4 5 6 7]
[ 0 1 2 3]]
在一些機(jī)器學(xué)習(xí)算法中家乘,我們常常需要對(duì)矩陣進(jìn)行轉(zhuǎn)置運(yùn)算:
In [19]: print(np.transpose(a)) #矩陣a的轉(zhuǎn)置
Out [19]: [[11 7 3]
[10 6 2]
[ 9 5 1]
[ 8 4 0]]
a.T
也同樣可以得到矩陣 a 的轉(zhuǎn)置:
In [20]: print(a.T)
Out [20]: [[11 7 3]
[10 6 2]
[ 9 5 1]
[ 8 4 0]]
用矩陣a的轉(zhuǎn)置乘以矩陣a也是常見(jiàn)的運(yùn)算:
In [21]: print((a.T).dot(a))
Out [21]: [[179 158 137 116]
[158 140 122 104]
[137 122 107 92]
[116 104 92 80]]
對(duì)訓(xùn)練數(shù)據(jù)預(yù)處理的時(shí)候,往往要對(duì)異常值進(jìn)行特殊處理藏澳,例如馍迄,對(duì)于矩陣a颈嚼,用數(shù)值9代替大于9的值,用5代替小于5的值:
In [22]: print(np.clip(a,5,9))
Out [22]: [[9 9 9 8]
[7 6 5 5]
[5 5 5 5]]
我們往往需要對(duì)矩陣中某一行或者某一列進(jìn)行操作:
In [23]: print(a[2,:]) #相當(dāng)于取二維數(shù)組中角標(biāo)為2的一整行
print(a[:,1]) #相當(dāng)于取二維數(shù)組中角標(biāo)為1的一整列
Out [23]: [3 2 1 0]
[10 6 2]
迭代矩陣中的每一行:
In [24]: for row in a:
print(row)
Out [24]: [11 10 9 8]
[7 6 5 4]
[3 2 1 0]
迭代矩陣的每一列委粉,可以借助矩陣的轉(zhuǎn)置操作:
In [25]: for col in a.T:
print(col)
Out [25]: [11 7 3]
[10 6 2]
[9 5 1]
[8 4 0]
用迭代器遍歷矩陣的每一個(gè)元素:
In [26]: for item in a.flat:
print(item)
Out [26]: 11
10
9
8
7
6
5
4
3
2
1
0
上下合并兩個(gè)數(shù)組:
In [27]: a = np.array([1,1,1])
b = np.array([2,2,2])
print(np.vstack((a,b))) #vertical stack 上下合并野芒,把a(bǔ)和b作為兩個(gè)元素 (a,b)為T(mén)uple
Out [27]: [[1 1 1]
[2 2 2]]
左右合并兩個(gè)數(shù)組:
In [28]: print(np.hstack((a,b))) #horizontal stack 左右合并
Out [28]: [1 1 1 2 2 2]
在數(shù)組上新增一個(gè)軸蓄愁,變成矩陣:
In [29]: print(a[:,np.newaxis]) #在列上新加一個(gè)軸
print(a[np.newaxis,:]) #在行上新加一個(gè)軸
Out [29]: [[1]
[1]
[1]]
[[1 1 1]]
我們可以通過(guò)新增加軸的方式將行向量轉(zhuǎn)成列向量:
In [30]: a = np.array([1,1,1])[:,np.newaxis]
b = np.array([2,2,2])[:,np.newaxis]
a,b
Out [30]: (array([[1],
[1],
[1]]), array([[2],
[2],
[2]]))
hstack
函數(shù)和 concatenate
函數(shù)均能左右合并兩個(gè)或多個(gè)列向量:
In [31]: print(np.hstack((a,b,b)))
print(np.concatenate((a,b,b),axis=1)) # axis表示左右合并
Out [31]: [[1 2 2]
[1 2 2]
[1 2 2]]
[[1 2 2]
[1 2 2]
[1 2 2]]
按照行的維度等量切割矩陣:
In [32]: a = np.arange(12).reshape((3,4))
print(a)
print(np.split(a,3,axis=0)) # 矩陣a有3行,可以按照行切割成3塊狞悲,除不盡會(huì)報(bào)錯(cuò)
Out [32]: [[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
按照列的維度等量切割矩陣:
In [33]: print(np.split(a,2,axis=1)) #有4列撮抓,可以分成兩塊 ,除不盡 會(huì)報(bào)錯(cuò)
Out [33]: [array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
我們也可以按照需要不等量切割矩陣:
In [34]: print(np.split(a,[1,1,2],axis=1)) # 按照(1摇锋,1丹拯,2)的方式對(duì)矩陣a進(jìn)行按照列的維度切割
Out [34]: [array([[0],
[4],
[8]]), array([], shape=(3, 0), dtype=int64), array([[1],
[5],
[9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
另一種切割的方法:
In [35]: print(np.vsplit(a,3)) #上下切分
print(np.hsplit(a,2)) #左右切分
Out [35]: [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
[array([[0, 1],
[4, 5],
[8, 9]]), array([[ 2, 3],
[ 6, 7],
[10, 11]])]
本篇到這里就要結(jié)束了,以上就是我在工作學(xué)習(xí)中荸恕,用到的常見(jiàn)的 numpy 庫(kù)方法乖酬,小伙伴們想了解更多的 Python 知識(shí),可以關(guān)注我的簡(jiǎn)書(shū)哦融求!