日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Numpy:高性能科学计算和数据分析的基础包

發(fā)布時(shí)間:2024/10/8 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Numpy:高性能科学计算和数据分析的基础包 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)入文件
    • 文件讀寫(xiě)
    • 文件保存
  • 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ú)需編寫(xiě)循環(huán))。
  • 線性代數(shù)、隨機(jī)數(shù)生成以及傅里葉變換功能。
  • 讀寫(xiě)磁盤(pán)數(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í)不需要寫(xiě)for循環(huán)。
  • Numpy底層使用C語(yǔ)言編寫(xiě),內(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 不能這么寫(xiě),會(huì)報(bào)錯(cuò) # a[:] = a[:] + 1 也不能這么寫(xiě),也會(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)位置元素的和,是否可以這么寫(xiě)? 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è)案例可以看出,在不寫(xiě)for循環(huán)的情況下,ndarray數(shù)組就可以非常方便的完成數(shù)學(xué)計(jì)算。在編寫(xiě)矢量或者矩陣的程序時(shí),可以像編寫(xiě)普通數(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ù)組。
# 導(dǎo)入numpy import numpy as np# 從list創(chuàng)建array a = [1,2,3,4,5,6] # 創(chuàng)建簡(jiǎn)單的列表 b = np.array(a) # 將列表轉(zhuǎn)換為數(shù)組 b array([1, 2, 3, 4, 5, 6])
  • arange:創(chuàng)建元素從0到10依次遞增2的數(shù)組。
# 通過(guò)np.arange創(chuàng)建 # 通過(guò)指定start, stop (不包括stop),interval來(lái)產(chǎn)生一個(gè)1維的ndarray a = np.arange(0, 10, 2) a array([0, 2, 4, 6, 8])
  • zeros:創(chuàng)建指定長(zhǎng)度或者形狀的全0數(shù)組。
# 創(chuàng)建全0的ndarray a = np.zeros([3,3]) a array([[0., 0., 0.],[0., 0., 0.],[0., 0., 0.]])
  • ones:創(chuàng)建指定長(zhǎng)度或者形狀的全1數(shù)組。
# 創(chuàng)建全1的ndarray a = np.ones([3,3]) a array([[1., 1., 1.],[1., 1., 1.],[1., 1., 1.]])

查看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ù)。
a = np.ones([3, 3]) print('a, dtype: {}, shape: {}, size: {}, ndim: {}'.format(a.dtype, a.shape, a.size, a.ndim)) a, dtype: float64, shape: (3, 3), size: 9, ndim: 2 import numpy as np b = np.random.rand(10, 10) b.shape (10, 10) b.size 100 b.ndim 2 b.dtype dtype('float64')

改變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ù)組的索引和切片

在編寫(xiě)模型過(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ù)種子
# 可以多次運(yùn)行,觀察程序輸出結(jié)果是否一致 # 如果不設(shè)置隨機(jī)數(shù)種子,觀察多次運(yùn)行輸出結(jié)果是否一致 np.random.seed(10) a = np.random.rand(3, 3) a array([[0.77132064, 0.02075195, 0.63364823],[0.74880388, 0.49850701, 0.22479665],[0.19806286, 0.76053071, 0.16911084]])
  • 均勻分布
# 生成均勻分布隨機(jī)數(shù),隨機(jī)數(shù)取值范圍在[0, 1)之間 a = np.random.rand(3, 3) a array([[0.08833981, 0.68535982, 0.95339335],[0.00394827, 0.51219226, 0.81262096],[0.61252607, 0.72175532, 0.29187607]]) # 生成均勻分布隨機(jī)數(shù),指定隨機(jī)數(shù)取值范圍和數(shù)組形狀 a = np.random.uniform(low = -1.0, high = 1.0, size=(2,2)) a array([[ 0.83554825, 0.42915157],[ 0.08508874, -0.7156599 ]])
  • 正態(tài)分布
# 生成標(biāo)準(zhǔn)正態(tài)分布隨機(jī)數(shù) a = np.random.randn(3, 3) a array([[ 1.484537 , -1.07980489, -1.97772828],[-1.7433723 , 0.26607016, 2.38496733],[ 1.12369125, 1.67262221, 0.09914922]]) # 生成正態(tài)分布隨機(jī)數(shù),指定均值loc和方差scale a = np.random.normal(loc = 1.0, scale = 1.0, size = (3,3)) a array([[2.39799638, 0.72875201, 1.61320418],[0.73268281, 0.45069099, 1.1327083 ],[0.52385799, 2.30847308, 1.19501328]])

隨機(jī)打亂ndarray數(shù)組順序

  • 隨機(jī)打亂1維ndarray數(shù)組順序,發(fā)現(xiàn)所有元素位置都被打亂了,代碼如下所示。
# 生成一維數(shù)組 a = np.arange(0, 30) print('before random shuffle: ', a) # 打亂一維數(shù)組順序 np.random.shuffle(a) print('after random shuffle: ', a) ('before random shuffle: ', 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])) ('after random shuffle: ', array([10, 21, 26, 7, 0, 23, 2, 17, 18, 20, 12, 6, 9, 3, 25, 5, 13,14, 24, 29, 1, 28, 11, 15, 27, 16, 19, 4, 22, 8]))

隨機(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ì)算方陣的逆。
# 矩陣相乘 a = np.arange(12) b = a.reshape([3, 4]) c = a.reshape([4, 3]) # 矩陣b的第二維大小,必須等于矩陣c的第一維大小 d = b.dot(c) # 等價(jià)于 np.dot(b, c) print('a: \n{}'.format(a)) print('b: \n{}'.format(b)) print('c: \n{}'.format(c)) print('d: \n{}'.format(d)) a: [ 0 1 2 3 4 5 6 7 8 9 10 11] b: [[ 0 1 2 3][ 4 5 6 7][ 8 9 10 11]] c: [[ 0 1 2][ 3 4 5][ 6 7 8][ 9 10 11]] d: [[ 42 48 54][114 136 158][186 224 262]] # numpy.linalg 中有一組標(biāo)準(zhǔn)的矩陣分解運(yùn)算以及諸如求逆和行列式之類的東西 # np.linalg.diag 以一維數(shù)組的形式返回方陣的對(duì)角線(或非對(duì)角線)元素, # 或?qū)⒁痪S數(shù)組轉(zhuǎn)換為方陣(非對(duì)角線元素為0) e = np.diag(d) f = np.diag(e) print('d: \n{}'.format(d)) print('e: \n{}'.format(e)) print('f: \n{}'.format(f)) d: [[ 42 48 54][114 136 158][186 224 262]] e: [ 42 136 262] f: [[ 42 0 0][ 0 136 0][ 0 0 262]] # trace, 計(jì)算對(duì)角線元素的和 g = np.trace(d) g 440 # det,計(jì)算行列式 h = np.linalg.det(d) h 1.3642420526593978e-11 # eig,計(jì)算特征值和特征向量 i = np.linalg.eig(d) i (array([4.36702561e+02, 3.29743887e+00, 3.13152204e-14]),array([[ 0.17716392, 0.77712552, 0.40824829],[ 0.5095763 , 0.07620532, -0.81649658],[ 0.84198868, -0.62471488, 0.40824829]])) # inv,計(jì)算方陣的逆 tmp = np.random.rand(3, 3) j = np.linalg.inv(tmp) j array([[-0.59449952, 1.39735912, -0.06654123],[ 1.56034184, -0.40734618, -0.48055062],[ 0.10659811, -0.62164179, 1.30437759]])

Numpy保存和導(dǎo)入文件

文件讀寫(xiě)

Numpy可以方便的進(jìn)行文件讀寫(xiě),如下面這種格式的文本文件:


# 使用np.fromfile從文本文件'housing.data'讀入數(shù)據(jù) # 這里要設(shè)置參數(shù)sep = ' ',表示使用空白字符來(lái)分隔數(shù)據(jù) # 空格或者回車(chē)都屬于空白字符,讀入的數(shù)據(jù)被轉(zhuǎn)化成1維數(shù)組 d = np.fromfile('./work/housing.data', sep = ' ') d array([6.320e-03, 1.800e+01, 2.310e+00, ..., 3.969e+02, 7.880e+00,1.190e+01])

文件保存

Numpy提供了save和load接口,直接將數(shù)組保存成文件(保存為.npy格式),或者從.npy文件中讀取數(shù)組。

# 產(chǎn)生隨機(jī)數(shù)組a a = np.random.rand(3,3) np.save('a.npy', a)# 從磁盤(pán)文件'a.npy'讀入數(shù)組 b = np.load('a.npy')# 檢查a和b的數(shù)值是否一樣 check = (a == b).all() check True

Numpy應(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)(x0)?

使用Numpy計(jì)算激活函數(shù)Sigmoid和ReLU的值,使用matplotlib畫(huà)出圖形,代碼如下所示。

# 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)######################################################### # 以下部分為畫(huà)圖程序# 設(shè)置兩個(gè)子圖窗口,將Sigmoid的函數(shù)圖像畫(huà)在左邊 f = plt.subplot(121) # 畫(huà)出函數(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ù)圖像畫(huà)在右邊 f = plt.subplot(122) # 畫(huà)出函數(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ì)算,并畫(huà)出其函數(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)寫(xiě)一段程序統(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。