Numpy:高性能科学计算和数据分析的基础包
Numpy:高性能科學(xué)計(jì)算和數(shù)據(jù)分析的基礎(chǔ)包
- 概述
- 基礎(chǔ)數(shù)據(jù)類型:ndarray數(shù)組
- 為什么引入ndarray數(shù)組
- 案例1:實(shí)現(xiàn)a+1的計(jì)算
- 案例2:實(shí)現(xiàn)c=a+b的計(jì)算
- 創(chuàng)建ndarray數(shù)組
- 查看ndarray數(shù)組的屬性
- 改變ndarray數(shù)組的數(shù)據(jù)類型和形狀
- ndarray數(shù)組的基本運(yùn)算
- 標(biāo)量和ndarray數(shù)組之間的運(yùn)算
- 兩個(gè)ndarray數(shù)組之間的運(yùn)算
- ndarray數(shù)組的索引和切片
- 一維ndarray數(shù)組的索引和切片
- 多維ndarray數(shù)組的索引和切片
- ndarray數(shù)組的統(tǒng)計(jì)方法
- 隨機(jī)數(shù)np.random
- 創(chuàng)建隨機(jī)ndarray數(shù)組
- 隨機(jī)打亂ndarray數(shù)組順序
- 隨機(jī)選取元素
- 線性代數(shù)
- Numpy保存和導(dǎo)入文件
- 文件讀寫
- 文件保存
- Numpy應(yīng)用舉例
- 計(jì)算激活函數(shù)Sigmoid和ReLU
- 圖像翻轉(zhuǎn)和裁剪
- 作業(yè)1:使用numpy計(jì)算tanh激活函數(shù)
- 作業(yè)2: 統(tǒng)計(jì)隨機(jī)生成矩陣中有多少個(gè)元素大于0
概述
Numpy(Numerical Python的簡(jiǎn)稱)是高性能科學(xué)計(jì)算和數(shù)據(jù)分析的基礎(chǔ)包。使用飛槳構(gòu)建神經(jīng)網(wǎng)絡(luò)模型時(shí),通常會(huì)使用Numpy實(shí)現(xiàn)數(shù)據(jù)預(yù)處理和一些模型指標(biāo)的計(jì)算,飛槳中的Tensor數(shù)據(jù)可以很方便的和ndarray數(shù)組進(jìn)行相互轉(zhuǎn)換。
Numpy具有如下功能:
- ndarray數(shù)組:一個(gè)具有矢量算術(shù)運(yùn)算和復(fù)雜廣播能力的多維數(shù)組,具有快速且節(jié)省空間的特點(diǎn)。
- 對(duì)整組數(shù)據(jù)進(jìn)行快速運(yùn)算的標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)(無(wú)需編寫循環(huán))。
- 線性代數(shù)、隨機(jī)數(shù)生成以及傅里葉變換功能。
- 讀寫磁盤數(shù)據(jù)、操作內(nèi)存映射文件。
本質(zhì)上,Numpy期望用戶在執(zhí)行“向量”操作時(shí),像使用“標(biāo)量”一樣輕松。讀者可以先在本機(jī)上運(yùn)行如下代碼,感受一下Numpy的便捷。
>>> import numpy as np >>> a = np.array([1,2,3,4]) >>> b = np.array([10,20,30,40]) >>> c = a + b >>> print (c) [11 22 33 44]基礎(chǔ)數(shù)據(jù)類型:ndarray數(shù)組
ndarray數(shù)組是Numpy的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),可以靈活、高效地處理多個(gè)元素的操作。本節(jié)主要從如下五部分展開(kāi)介紹:
- 為什么引入ndarray數(shù)組
- 如何創(chuàng)建ndarray數(shù)組
- ndarray數(shù)組的基本運(yùn)算
- ndarray數(shù)組的切片和索引
- ndarray數(shù)組的統(tǒng)計(jì)運(yùn)算
為什么引入ndarray數(shù)組
Python中的list列表也可以非常靈活的處理多個(gè)元素的操作,但效率卻非常低。與之比較,ndarray數(shù)組具有如下特點(diǎn):
- ndarray數(shù)組中所有元素的數(shù)據(jù)類型相同、數(shù)據(jù)地址連續(xù),批量操作數(shù)組元素時(shí)速度更快。而list列表中元素的數(shù)據(jù)類型可能不同,需要通過(guò)尋址方式找到下一個(gè)元素。
- ndarray數(shù)組支持廣播機(jī)制,矩陣運(yùn)算時(shí)不需要寫for循環(huán)。
- Numpy底層使用C語(yǔ)言編寫,內(nèi)置并行計(jì)算功能,運(yùn)行速度高于Python代碼。
下面通過(guò)幾個(gè)實(shí)際例子體會(huì)一下,在完成同一個(gè)任務(wù)時(shí),使用ndarray數(shù)組和list列表的差異。
案例1:實(shí)現(xiàn)a+1的計(jì)算
# Python原生的list # 假設(shè)有兩個(gè)list a = [1, 2, 3, 4, 5] b = [2, 3, 4, 5, 6]# 完成如下計(jì)算 # 對(duì)a的每個(gè)元素 + 1 # a = a + 1 不能這么寫,會(huì)報(bào)錯(cuò) # a[:] = a[:] + 1 也不能這么寫,也會(huì)報(bào)錯(cuò) for i in range(5):a[i] = a[i] + 1 a [2, 3, 4, 5, 6] # 使用ndarray import numpy as np a = np.array([1, 2, 3, 4, 5]) a = a + 1 a array([2, 3, 4, 5, 6])案例2:實(shí)現(xiàn)c=a+b的計(jì)算
# 計(jì)算 a和b中對(duì)應(yīng)位置元素的和,是否可以這么寫? a = [1, 2, 3, 4, 5] b = [2, 3, 4, 5, 6] c = a + b # 檢查輸出發(fā)現(xiàn),不是想要的結(jié)果 c [1, 2, 3, 4, 5, 2, 3, 4, 5, 6] # 使用for循環(huán),完成兩個(gè)list對(duì)應(yīng)位置元素相加 c = [] for i in range(5):c.append(a[i] + b[i]) c [3, 5, 7, 9, 11] # 使用numpy中的ndarray完成兩個(gè)ndarray相加 import numpy as np a = np.array([1, 2, 3, 4, 5]) b = np.array([2, 3, 4, 5, 6]) c = a + b c array([ 3, 5, 7, 9, 11])通過(guò)上面的兩個(gè)案例可以看出,在不寫for循環(huán)的情況下,ndarray數(shù)組就可以非常方便的完成數(shù)學(xué)計(jì)算。在編寫矢量或者矩陣的程序時(shí),可以像編寫普通數(shù)值一樣,使得代碼極其簡(jiǎn)潔。
另外,ndarray數(shù)組還提供了廣播機(jī)制,它會(huì)按一定規(guī)則自動(dòng)對(duì)數(shù)組的維度進(jìn)行擴(kuò)展以完成計(jì)算。如下面例子所示,1維數(shù)組和2維數(shù)組進(jìn)行相加操作,ndarray數(shù)組會(huì)自動(dòng)擴(kuò)展1維數(shù)組的維度,然后再對(duì)每個(gè)位置的元素分別相加。
# 自動(dòng)廣播機(jī)制,1維數(shù)組和2維數(shù)組相加# 二維數(shù)組維度 2x5 # array([[ 1, 2, 3, 4, 5], # [ 6, 7, 8, 9, 10]]) d = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]) # c是一維數(shù)組,維度5 # array([ 4, 6, 8, 10, 12]) c = np.array([ 4, 6, 8, 10, 12]) e = d + c e array([[ 5, 8, 11, 14, 17],[10, 13, 16, 19, 22]])創(chuàng)建ndarray數(shù)組
創(chuàng)建ndarray數(shù)組最簡(jiǎn)單的方式就是使用array函數(shù),它接受一切序列型的對(duì)象(包括其他數(shù)組),然后產(chǎn)生一個(gè)新的含有傳入數(shù)據(jù)的numpy數(shù)組。下面通過(guò)實(shí)例體會(huì)下array、arange、zeros、ones四個(gè)主要函數(shù)的用法。
- array:創(chuàng)建嵌套序列(比如由一組等長(zhǎng)列表組成的列表),并轉(zhuǎn)換為一個(gè)多維數(shù)組。
- arange:創(chuàng)建元素從0到10依次遞增2的數(shù)組。
- zeros:創(chuàng)建指定長(zhǎng)度或者形狀的全0數(shù)組。
- ones:創(chuàng)建指定長(zhǎng)度或者形狀的全1數(shù)組。
查看ndarray數(shù)組的屬性
ndarray的屬性包括shape、dtype、size和ndim等,通過(guò)如下代碼可以查看ndarray數(shù)組的屬性。
- shape:數(shù)組的形狀 ndarray.shape,1維數(shù)組(N, ),二維數(shù)組(M, N),三維數(shù)組(M, N, K)。
- dtype:數(shù)組的數(shù)據(jù)類型。
- size:數(shù)組中包含的元素個(gè)數(shù) ndarray.size,其大小等于各個(gè)維度的長(zhǎng)度的乘積。
- ndim:數(shù)組的維度大小,ndarray.ndim, 其大小等于ndarray.shape所包含元素的個(gè)數(shù)。
改變ndarray數(shù)組的數(shù)據(jù)類型和形狀
創(chuàng)建ndarray之后,可以對(duì)其數(shù)據(jù)類型或形狀進(jìn)行修改,代碼如下所示。
# 轉(zhuǎn)化數(shù)據(jù)類型 b = a.astype(np.int64) print('b, dtype: {}, shape: {}'.format(b.dtype, b.shape))# 改變形狀 c = a.reshape([1, 9]) print('c, dtype: {}, shape: {}'.format(c.dtype, c.shape)) b, dtype: int64, shape: (3, 3) c, dtype: float64, shape: (1, 9)ndarray數(shù)組的基本運(yùn)算
ndarray數(shù)組可以像普通的數(shù)值型變量一樣進(jìn)行加減乘除操作,主要包含如下兩種運(yùn)算:
- 標(biāo)量和ndarray數(shù)組之間的運(yùn)算
- 兩個(gè)ndarray數(shù)組之間的運(yùn)算
標(biāo)量和ndarray數(shù)組之間的運(yùn)算
標(biāo)量和ndarray數(shù)組之間的運(yùn)算主要包括除法、乘法、加法和減法運(yùn)算,具體代碼如下所示。
# 標(biāo)量除以數(shù)組,用標(biāo)量除以數(shù)組的每一個(gè)元素 arr = np.array([[1., 2., 3.], [4., 5., 6.]]) 1. / arr array([[1. , 0.5 , 0.33333333],[0.25 , 0.2 , 0.16666667]]) # 標(biāo)量乘以數(shù)組,用標(biāo)量乘以數(shù)組的每一個(gè)元素 arr = np.array([[1., 2., 3.], [4., 5., 6.]]) 2.0 * arr array([[ 2., 4., 6.],[ 8., 10., 12.]]) # 標(biāo)量加上數(shù)組,用標(biāo)量加上數(shù)組的每一個(gè)元素 arr = np.array([[1., 2., 3.], [4., 5., 6.]]) 2.0 + arr array([[3., 4., 5.],[6., 7., 8.]]) # 標(biāo)量減去數(shù)組,用標(biāo)量減去數(shù)組的每一個(gè)元素 arr = np.array([[1., 2., 3.], [4., 5., 6.]]) 2.0 - arr array([[ 1., 0., -1.],[-2., -3., -4.]])兩個(gè)ndarray數(shù)組之間的運(yùn)算
兩個(gè)ndarray數(shù)組之間的運(yùn)算主要包括減法、加法、乘法、除法和開(kāi)根號(hào)運(yùn)算,具體代碼如下所示。
# 數(shù)組 減去 數(shù)組, 用對(duì)應(yīng)位置的元素相減 arr1 = np.array([[1., 2., 3.], [4., 5., 6.]]) arr2 = np.array([[11., 12., 13.], [21., 22., 23.]]) arr1 - arr2 array([[-10., -10., -10.],[-17., -17., -17.]]) # 數(shù)組 加上 數(shù)組, 用對(duì)應(yīng)位置的元素相加 arr1 = np.array([[1., 2., 3.], [4., 5., 6.]]) arr2 = np.array([[11., 12., 13.], [21., 22., 23.]]) arr1 + arr2 array([[12., 14., 16.],[25., 27., 29.]]) # 數(shù)組 乘以 數(shù)組,用對(duì)應(yīng)位置的元素相乘 arr1 * arr2 array([[ 11., 24., 39.],[ 84., 110., 138.]]) # 數(shù)組 除以 數(shù)組,用對(duì)應(yīng)位置的元素相除 arr1 / arr2 array([[0.09090909, 0.16666667, 0.23076923],[0.19047619, 0.22727273, 0.26086957]]) # 數(shù)組開(kāi)根號(hào),將每個(gè)位置的元素都開(kāi)根號(hào) arr ** 0.5 array([[1. , 1.41421356, 1.73205081],[2. , 2.23606798, 2.44948974]])ndarray數(shù)組的索引和切片
在編寫模型過(guò)程中,通常需要訪問(wèn)或者修改ndarray數(shù)組某個(gè)位置的元素,則需要使用ndarray數(shù)組的索引。有些情況下可能需要訪問(wèn)或者修改一些區(qū)域的元素,則需要使用ndarray數(shù)組的切片。
ndarray數(shù)組的索引和切片的使用方式與Python中的list類似。通過(guò)[ -n , n-1 ]的下標(biāo)進(jìn)行索引,通過(guò)內(nèi)置的slice函數(shù),設(shè)置其start,stop和step參數(shù)進(jìn)行切片,從原數(shù)組中切割出一個(gè)新數(shù)組。
ndarray數(shù)組的索引是一個(gè)內(nèi)容豐富的主題,因?yàn)檫x取數(shù)據(jù)子集或的單個(gè)元素的方式有很多。下面從一維數(shù)組和多維數(shù)組兩個(gè)維度介紹索引和切片的方法。
一維ndarray數(shù)組的索引和切片
從表面上看,一維數(shù)組跟Python列表的功能類似,它們重要區(qū)別在于:數(shù)組切片產(chǎn)生的新數(shù)組,還是指向原來(lái)的內(nèi)存區(qū)域,數(shù)據(jù)不會(huì)被復(fù)制,視圖上的任何修改都會(huì)直接反映到源數(shù)組上。將一個(gè)標(biāo)量值賦值給一個(gè)切片時(shí),該值會(huì)自動(dòng)傳播到整個(gè)選區(qū)。
# 1維數(shù)組索引和切片 a = np.arange(30) a[10] 10 a = np.arange(30) b = a[4:7] b array([4, 5, 6]) #將一個(gè)標(biāo)量值賦值給一個(gè)切片時(shí),該值會(huì)自動(dòng)傳播到整個(gè)選區(qū)。 a = np.arange(30) a[4:7] = 10 a array([ 0, 1, 2, 3, 10, 10, 10, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]) # 數(shù)組切片產(chǎn)生的新數(shù)組,還是指向原來(lái)的內(nèi)存區(qū)域,數(shù)據(jù)不會(huì)被復(fù)制。 # 視圖上的任何修改都會(huì)直接反映到源數(shù)組上。 a = np.arange(30) arr_slice = a[4:7] arr_slice[0] = 100 a, arr_slice (array([ 0, 1, 2, 3, 100, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,26, 27, 28, 29]), array([100, 5, 6])) # 通過(guò)copy給新數(shù)組創(chuàng)建不同的內(nèi)存空間 a = np.arange(30) arr_slice = a[4:7] arr_slice = np.copy(arr_slice) arr_slice[0] = 100 a, arr_slice (array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]),array([100, 5, 6]))多維ndarray數(shù)組的索引和切片
多維ndarray數(shù)組的索引和切片具有如下特點(diǎn):
- 在多維數(shù)組中,各索引位置上的元素不再是標(biāo)量而是多維數(shù)組。
- 以逗號(hào)隔開(kāi)的索引列表來(lái)選取單個(gè)元素。
- 在多維數(shù)組中,如果省略了后面的索引,則返回對(duì)象會(huì)是一個(gè)維度低一點(diǎn)的ndarray。
多維ndarray數(shù)組的索引代碼如下所示。
# 創(chuàng)建一個(gè)多維數(shù)組 a = np.arange(30) arr3d = a.reshape(5, 3, 2) arr3d array([[[ 0, 1],[ 2, 3],[ 4, 5]],[[ 6, 7],[ 8, 9],[10, 11]],[[12, 13],[14, 15],[16, 17]],[[18, 19],[20, 21],[22, 23]],[[24, 25],[26, 27],[28, 29]]]) # 只有一個(gè)索引指標(biāo)時(shí),會(huì)在第0維上索引,后面的維度保持不變 arr3d[0] array([[0, 1],[2, 3],[4, 5]]) # 兩個(gè)索引指標(biāo) arr3d[0][1] array([2, 3]) # 兩個(gè)索引指標(biāo) arr3d[0, 1] array([2, 3])多維ndarray數(shù)組的切片代碼如下所示。
# 創(chuàng)建一個(gè)數(shù)組a = np.arange(24) a array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20, 21, 22, 23]) # reshape成一個(gè)二維數(shù)組 a = a.reshape([6, 4]) a array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23]]) # 使用for語(yǔ)句生成list [k for k in range(0, 6, 2)] [0, 2, 4] # 結(jié)合上面列出的for語(yǔ)句的用法 # 使用for語(yǔ)句對(duì)數(shù)組進(jìn)行切片 # 下面的代碼會(huì)生成多個(gè)切片構(gòu)成的list # k in range(0, 6, 2) 決定了k的取值可以是0, 2, 4 # 產(chǎn)生的list的包含三個(gè)切片 # 第一個(gè)元素是a[0 : 0+2], # 第二個(gè)元素是a[2 : 2+2], # 第三個(gè)元素是a[4 : 4+2] slices = [a[k:k+2] for k in range(0, 6, 2)] slices [array([[0, 1, 2, 3],[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],[12, 13, 14, 15]]), array([[16, 17, 18, 19],[20, 21, 22, 23]])] slices[0] array([[0, 1, 2, 3],[4, 5, 6, 7]])ndarray數(shù)組的統(tǒng)計(jì)方法
可以通過(guò)數(shù)組上的一組數(shù)學(xué)函數(shù)對(duì)整個(gè)數(shù)組或某個(gè)軸向的數(shù)據(jù)進(jìn)行統(tǒng)計(jì)計(jì)算。主要包括如下統(tǒng)計(jì)方法:
- mean:計(jì)算算術(shù)平均數(shù),零長(zhǎng)度數(shù)組的mean為NaN。
- std和var:計(jì)算標(biāo)準(zhǔn)差和方差,自由度可調(diào)(默認(rèn)為n)。
- sum :對(duì)數(shù)組中全部或某軸向的元素求和,零長(zhǎng)度數(shù)組的sum為0。
- max和min:計(jì)算最大值和最小值。
- argmin和argmax:分別為最大和最小元素的索引。
- cumsum:計(jì)算所有元素的累加。
- cumprod:計(jì)算所有元素的累積。
說(shuō)明:
sum、mean以及標(biāo)準(zhǔn)差std等聚合計(jì)算既可以當(dāng)做數(shù)組的實(shí)例方法調(diào)用,也可以當(dāng)做Numpy函數(shù)使用。
# 計(jì)算均值,使用arr.mean() 或 np.mean(arr),二者是等價(jià)的 arr = np.array([[1,2,3], [4,5,6], [7,8,9]]) arr.mean(), np.mean(arr) (5.0, 5.0) # 求和 arr.sum(), np.sum(arr) (45, 45) # 求最大值 arr.max(), np.max(arr) (9, 9) # 求最小值 arr.min(), np.min(arr) (1, 1) # 指定計(jì)算的維度 # 沿著第1維求平均,也就是將[1, 2, 3]取平均等于2,[4, 5, 6]取平均等于5,[7, 8, 9]取平均等于8 arr.mean(axis = 1) # 按行取平均 array([2., 5., 8.]) # 沿著第0維求和,也就是將[1, 4, 7]求和等于12,[2, 5, 8]求和等于15,[3, 6, 9]求和等于18 arr.sum(axis=0) # 按列取平均 array([12, 15, 18]) # 沿著第0維求最大值,也就是將[1, 4, 7]求最大值等于7,[2, 5, 8]求最大值等于8,[3, 6, 9]求最大值等于9 arr.max(axis=0) array([7, 8, 9]) # 沿著第1維求最小值,也就是將[1, 2, 3]求最小值等于1,[4, 5, 6]求最小值等于4,[7, 8, 9]求最小值等于7 arr.min(axis=1) array([1, 4, 7]) # 計(jì)算標(biāo)準(zhǔn)差 arr.std() 2.581988897471611 # 計(jì)算方差 arr.var() 6.666666666666667 # 找出最大元素的索引 arr.argmax(), arr.argmax(axis=0), arr.argmax(axis=1) (8, array([2, 2, 2]), array([2, 2, 2])) # 找出最小元素的索引 arr.argmin(), arr.argmin(axis=0), arr.argmin(axis=1) (0, array([0, 0, 0]), array([0, 0, 0]))
隨機(jī)數(shù)np.random
主要介紹創(chuàng)建ndarray隨機(jī)數(shù)組以及隨機(jī)打亂順序、隨機(jī)選取元素等相關(guān)操作的方法。
創(chuàng)建隨機(jī)ndarray數(shù)組
創(chuàng)建隨機(jī)ndarray數(shù)組主要包含設(shè)置隨機(jī)種子、均勻分布和正態(tài)分布三部分內(nèi)容,具體代碼如下所示。
- 設(shè)置隨機(jī)數(shù)種子
- 均勻分布
- 正態(tài)分布
隨機(jī)打亂ndarray數(shù)組順序
- 隨機(jī)打亂1維ndarray數(shù)組順序,發(fā)現(xiàn)所有元素位置都被打亂了,代碼如下所示。
隨機(jī)打亂2維ndarray數(shù)組順序,發(fā)現(xiàn)只有行的順序被打亂了,列順序不變,代碼如下所示。
# 生成一維數(shù)組 a = np.arange(0, 30) # 將一維數(shù)組轉(zhuǎn)化成2維數(shù)組 a = a.reshape(10, 3) print('before random shuffle: \n{}'.format(a)) # 打亂一維數(shù)組順序 np.random.shuffle(a) print('after random shuffle: \n{}'.format(a)) before random shuffle: [[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11][12 13 14][15 16 17][18 19 20][21 22 23][24 25 26][27 28 29]] after random shuffle: [[15 16 17][12 13 14][27 28 29][ 3 4 5][ 9 10 11][21 22 23][18 19 20][ 0 1 2][ 6 7 8][24 25 26]]隨機(jī)選取元素
# 隨機(jī)選取部分元素 a = np.arange(30) b = np.random.choice(a, size=5) b array([ 0, 24, 12, 5, 4])線性代數(shù)
線性代數(shù)(如矩陣乘法、矩陣分解、行列式以及其他方陣數(shù)學(xué)等)是任何數(shù)組庫(kù)的重要組成部分,Numpy中實(shí)現(xiàn)了線性代數(shù)中常用的各種操作,并形成了numpy.linalg線性代數(shù)相關(guān)的模塊。本節(jié)主要介紹如下函數(shù):
- diag:以一維數(shù)組的形式返回方陣的對(duì)角線(或非對(duì)角線)元素,或?qū)⒁痪S數(shù)組轉(zhuǎn)換為方陣(非對(duì)角線元素為0)。
- dot:矩陣乘法。
- trace:計(jì)算對(duì)角線元素的和。
- det:計(jì)算矩陣行列式。
- eig:計(jì)算方陣的特征值和特征向量。
- inv:計(jì)算方陣的逆。
Numpy保存和導(dǎo)入文件
文件讀寫
Numpy可以方便的進(jìn)行文件讀寫,如下面這種格式的文本文件:
文件保存
Numpy提供了save和load接口,直接將數(shù)組保存成文件(保存為.npy格式),或者從.npy文件中讀取數(shù)組。
# 產(chǎn)生隨機(jī)數(shù)組a a = np.random.rand(3,3) np.save('a.npy', a)# 從磁盤文件'a.npy'讀入數(shù)組 b = np.load('a.npy')# 檢查a和b的數(shù)值是否一樣 check = (a == b).all() check TrueNumpy應(yīng)用舉例
計(jì)算激活函數(shù)Sigmoid和ReLU
使用ndarray數(shù)組可以很方便的構(gòu)建數(shù)學(xué)函數(shù),并利用其底層的矢量計(jì)算能力快速實(shí)現(xiàn)計(jì)算。下面以神經(jīng)網(wǎng)絡(luò)中比較常用激活函數(shù)Sigmoid和ReLU為例,介紹代碼實(shí)現(xiàn)過(guò)程。
- 計(jì)算Sigmoid激活函數(shù)
y=11+e?xy = \frac{1}{1 + e^{-x}}y=1+e?x1?
- 計(jì)算ReLU激活函數(shù)
y={0,(x<0)x,(x≥0)y=\left\{ \begin{aligned} 0 & , & (x<0) \\ x & , & (x\ge 0) \end{aligned} \right.y={0x?,,?(x<0)(x≥0)?
使用Numpy計(jì)算激活函數(shù)Sigmoid和ReLU的值,使用matplotlib畫出圖形,代碼如下所示。
# ReLU和Sigmoid激活函數(shù)示意圖 import numpy as np %matplotlib inline import matplotlib.pyplot as plt import matplotlib.patches as patches#設(shè)置圖片大小 plt.figure(figsize=(8, 3))# x是1維數(shù)組,數(shù)組大小是從-10. 到10.的實(shí)數(shù),每隔0.1取一個(gè)點(diǎn) x = np.arange(-10, 10, 0.1) # 計(jì)算 Sigmoid函數(shù) s = 1.0 / (1 + np.exp(- x))# 計(jì)算ReLU函數(shù) y = np.clip(x, a_min = 0., a_max = None)######################################################### # 以下部分為畫圖程序# 設(shè)置兩個(gè)子圖窗口,將Sigmoid的函數(shù)圖像畫在左邊 f = plt.subplot(121) # 畫出函數(shù)曲線 plt.plot(x, s, color='r') # 添加文字說(shuō)明 plt.text(-5., 0.9, r'$y=\sigma(x)$', fontsize=13) # 設(shè)置坐標(biāo)軸格式 currentAxis=plt.gca() currentAxis.xaxis.set_label_text('x', fontsize=15) currentAxis.yaxis.set_label_text('y', fontsize=15)# 將ReLU的函數(shù)圖像畫在右邊 f = plt.subplot(122) # 畫出函數(shù)曲線 plt.plot(x, y, color='g') # 添加文字說(shuō)明 plt.text(-3.0, 9, r'$y=ReLU(x)$', fontsize=13) # 設(shè)置坐標(biāo)軸格式 currentAxis=plt.gca() currentAxis.xaxis.set_label_text('x', fontsize=15) currentAxis.yaxis.set_label_text('y', fontsize=15)plt.show()圖像翻轉(zhuǎn)和裁剪
圖像是由像素點(diǎn)構(gòu)成的矩陣,其數(shù)值可以用ndarray來(lái)表示。將上述介紹的操作用在圖像數(shù)據(jù)對(duì)應(yīng)的ndarray上,可以很輕松的實(shí)現(xiàn)圖片的翻轉(zhuǎn)、裁剪和亮度調(diào)整,具體代碼和效果如下所示。
# 導(dǎo)入需要的包 import numpy as np import matplotlib.pyplot as plt from PIL import Image# 讀入圖片 image = Image.open('./work/images/000000001584.jpg') image = np.array(image) # 查看數(shù)據(jù)形狀,其形狀是[H, W, 3], # 其中H代表高度, W是寬度,3代表RGB三個(gè)通道 image.shape (612, 612, 3) # 原始圖片 plt.imshow(image) <matplotlib.image.AxesImage at 0x7fefe4f56290> # 垂直方向翻轉(zhuǎn) # 這里使用數(shù)組切片的方式來(lái)完成, # 相當(dāng)于將圖片最后一行挪到第一行, # 倒數(shù)第二行挪到第二行,..., # 第一行挪到倒數(shù)第一行 # 對(duì)于行指標(biāo),使用::-1來(lái)表示切片, # 負(fù)數(shù)步長(zhǎng)表示以最后一個(gè)元素為起點(diǎn),向左走尋找下一個(gè)點(diǎn) # 對(duì)于列指標(biāo)和RGB通道,僅使用:表示該維度不改變 image2 = image[::-1, :, :] plt.imshow(image2) <matplotlib.image.AxesImage at 0x7fefe4ecc850> # 水平方向翻轉(zhuǎn) image3 = image[:, ::-1, :] plt.imshow(image3) <matplotlib.image.AxesImage at 0x7fefe4e35f10> # 保存圖片 im3 = Image.fromarray(image3) im3.save('im3.jpg') # 高度方向裁剪 H, W = image.shape[0], image.shape[1] # 注意此處用整除,H_start必須為整數(shù) H1 = H // 2 H2 = H image4 = image[H1:H2, :, :] plt.imshow(image4) <matplotlib.image.AxesImage at 0x7fefe4e2cc10> # 寬度方向裁剪 W1 = W//6 W2 = W//3 * 2 image5 = image[:, W1:W2, :] plt.imshow(image5) <matplotlib.image.AxesImage at 0x7fefe4d2e050> # 兩個(gè)方向同時(shí)裁剪 image5 = image[H1:H2, \W1:W2, :] plt.imshow(image5) <matplotlib.image.AxesImage at 0x7fefe4d09b10> # 調(diào)整亮度 image6 = image * 0.5 plt.imshow(image6.astype('uint8')) <matplotlib.image.AxesImage at 0x7fefe4367fd0> # 調(diào)整亮度 image7 = image * 2.0 # 由于圖片的RGB像素值必須在0-255之間,會(huì)發(fā)生溢出 plt.imshow(image7.astype('uint8')) # 調(diào)整亮度 image7 = image * 2.0 # 由于圖片的RGB像素值必須在0-255之間, # 此處使用np.clip進(jìn)行數(shù)值裁剪 image7 = np.clip(image7, \a_min=None, a_max=255.) plt.imshow(image7.astype('uint8')) <matplotlib.image.AxesImage at 0x7fefe42e4990> #高度方向每隔一行取像素點(diǎn) image8 = image[::2, :, :] plt.imshow(image8) #寬度方向每隔一列取像素點(diǎn) image9 = image[:, ::2, :] plt.imshow(image9) #間隔行列采樣,圖像尺寸會(huì)減半,清晰度變差 image10 = image[::2, ::2, :] plt.imshow(image10) image10.shape (306, 306, 3)作業(yè)1:使用numpy計(jì)算tanh激活函數(shù)
tanh是神經(jīng)網(wǎng)絡(luò)中常用的一種激活函數(shù),其定義如下:
y=ex?e?xex+e?xy = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}y=ex+e?xex?e?x?
請(qǐng)參照講義中Sigmoid激活函數(shù)的計(jì)算程序,用numpy實(shí)現(xiàn)tanh函數(shù)的計(jì)算,并畫出其函數(shù)曲線。
import numpy as np import matplotlib.pyplot as pltx = np.arange(-10., 10., 0.1) y = (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))plt.plot(x, y, color='r') plt.text(-8., 0.9, r'$y = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}$', fontsize='20') # 設(shè)置坐標(biāo)軸格式 currentAxis = plt.gca() currentAxis.xaxis.set_label_text('x', fontsize=15) currentAxis.yaxis.set_label_text('y', fontsize=15) plt.show()作業(yè)2: 統(tǒng)計(jì)隨機(jī)生成矩陣中有多少個(gè)元素大于0
假設(shè)使用np.random.randn生成了隨機(jī)數(shù)構(gòu)成的矩陣:
p = np.random.randn(10, 10)請(qǐng)寫一段程序統(tǒng)計(jì)其中有多少個(gè)元素大于0?
提示:可以試下使用 q = (p > 0),觀察q是什么的數(shù)據(jù)類型和元素的取值。
p = np.random.randn(10, 10) print(p) q = (p > 0) print(q) gt_zeros = 0 for i in range(q.shape[0]):for j in range(q.shape[1]):if q[i][j] == True:gt_zeros += 1 print(gt_zeros)[[-0.38732292 -1.22679568 0.31236295 1.03279217 1.09965555 0.03400653
0.20423679 0.46102312 -0.06259861 -0.81071163]
[-1.66649224 0.07693191 -0.67912898 -0.50280616 -0.02505431 0.49763568
0.31897585 1.15265695 0.77989532 1.6062476 ]
[-1.34527513 0.70690703 0.06248045 1.28020171 0.70565811 0.57137282
-0.57306477 -0.42059354 2.45657154 -0.74566249]
[ 1.49276577 -0.51783348 -0.10772031 -0.71668211 -0.11371754 0.72771595
-0.41651344 0.50799406 -1.92331468 -0.72137913]
[-0.87331894 1.47201095 0.89948687 0.61737263 0.05318438 0.91925106
0.11471586 0.81959069 1.05926547 0.78230119]
[-0.39895178 0.12779079 0.0707294 -0.13315135 -0.12216901 -2.57047366
0.52459437 1.66376507 -0.12379566 0.26056764]
[ 1.40847093 -0.48087898 -0.52603037 1.00118688 0.18182928 0.78925785
-0.19340237 -0.51369058 0.54722812 -2.27085893]
[ 0.45131471 -0.56006753 0.88621361 -0.00927247 0.25484496 -2.08411595
1.2533057 0.81693454 0.10472067 0.59373638]
[ 1.6860616 -0.81854015 0.15086979 -0.01910994 -0.22888765 -0.17013442
0.35297974 0.907637 -1.53127124 -0.71607206]
[-0.11395618 0.63816421 1.14237617 -1.11256221 0.13971277 0.02803697
-2.03464592 -0.32906681 -0.99382472 -0.11581731]]
[[False False True True True True True True False False]
[False True False False False True True True True True]
[False True True True True True False False True False]
[ True False False False False True False True False False]
[False True True True True True True True True True]
[False True True False False False True True False True]
[ True False False True True True False False True False]
[ True False True False True False True True True True]
[ True False True False False False True True False False]
[False True True False True True False False False False]]
55
總結(jié)
以上是生活随笔為你收集整理的Numpy:高性能科学计算和数据分析的基础包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 机器学习理论《统计学习方法》学习笔记:第
- 下一篇: 深度学习入门之线性模型和梯度下降