NumPy(Numerical Python) 是 Python 語言的一個(gè)擴(kuò)展程序庫,支持大量的維度數(shù)組與矩陣運(yùn)算,此外也針對(duì)數(shù)組運(yùn)算提供大量的數(shù)學(xué)函數(shù)庫。
常用向量張量(Tensor):Tensor = multi-dimensional array of numbers 張量是一個(gè)多維數(shù)組,它是標(biāo)量,向量,矩陣的高維擴(kuò)展 ,是一個(gè)數(shù)據(jù)容器,張量是矩陣向任意維度的推廣
標(biāo)量(scalar):只有一個(gè)數(shù)字的張量叫標(biāo)量(也叫標(biāo)量張量、零維張量、0D 張量)
向量(vector):數(shù)字組成的數(shù)組叫作向量(vector)或一維張量(1D 張量)。一維張量只有一個(gè)軸。下面是一個(gè) Numpy 向量
矩陣(matrix):是一個(gè)按照長(zhǎng)方陣列排列的復(fù)數(shù)或?qū)崝?shù)集合,矩陣是二維張量(2D 張量)
3D 張量與n 維張量 np.array([[[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]], [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]], [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]]]) 將多個(gè) 3D 張量組合成一個(gè)數(shù)組,可以創(chuàng)建一個(gè) 4D 張量,以此類推。深度學(xué)習(xí)處理的一般是 0D 到 4D 的張量,但處理視頻數(shù)據(jù)時(shí)可能會(huì)遇到 5D 張量。 張量屬性張量是由以下三個(gè)關(guān)鍵屬性來定義的。
data: Tensor的值; 數(shù)據(jù)張量向量數(shù)據(jù):2D 張量,形狀為 (samples, features)這是最常見的數(shù)據(jù)。對(duì)于這種數(shù)據(jù)集,每個(gè)數(shù)據(jù)點(diǎn)都被編碼為一個(gè)向量,因此一個(gè)數(shù)據(jù)批量就被編碼為 2D 張量(即向量組成的數(shù)組),其中第一個(gè)軸是樣本軸,第二個(gè)軸是特征軸。
時(shí)間序列數(shù)據(jù)或序列數(shù)據(jù):3D 張量,形狀為 (samples, timesteps, features)當(dāng)時(shí)間(或序列順序)對(duì)于數(shù)據(jù)很重要時(shí),應(yīng)該將數(shù)據(jù)存儲(chǔ)在帶有時(shí)間軸的 3D 張量中。每個(gè)樣本可以被編碼為一個(gè)向量序列(即 2D 張量),因此一個(gè)數(shù)據(jù)批量就被編碼為一個(gè) 3D 張量(見下圖)
我們來看幾個(gè)例子。
圖像:3D 張量 形狀為 (height,width,channels)圖像通常具有三個(gè)維度:高度、寬度和通道。通常通道為3=R、G、B 圖像:4D張量,形狀為 (samples, height, width, channels) 或 (samples, channels,height, width) 。圖像通常具有三個(gè)維度:高度、寬度和顏色深度。雖然灰度圖像(比如 MNIST 數(shù)字圖像)只有一個(gè)顏色通道,因此可以保存在 2D 張量中,但按照慣例,圖像張量始終都是 3D 張量,灰度圖像的彩色通道只有一維。因此,如果圖像大小為 256×256,那么 128 張灰度圖像組成的批量可以保存在一個(gè)形狀為 (128, 256, 256, 1) 的張量中,而 128 張彩色圖像組成的批量則可以保存在一個(gè)形狀為 (128, 256, 256, 3) 的張量中。 Google 的 TensorFlow 機(jī)器學(xué)習(xí)框架將顏色深度軸放在最后: (samples, height, width, color_depth) 。與此相反,Theano將圖像深度軸放在批量軸之后: (samples, color_depth, height, width) 。如果采用 Theano 約定,前面的兩個(gè)例子將變成 (128, 1, 256, 256) 和 (128, 3, 256, 256) 。Keras 框架同時(shí)支持這兩種格式。 如下圖所示是一張普通的水果圖片,按照RGB三原色表示,其可以拆分為紅色、綠色和藍(lán)色的三張灰度圖片,如果將這種表示方法用張量的形式寫出來,就是圖中最下方的那張表格
用四階張量表示一個(gè)包含多張圖片的數(shù)據(jù)集,其中的四個(gè)維度分別是:圖片在數(shù)據(jù)集中的編號(hào),圖片高度、寬度,以及色彩數(shù)據(jù)。 視頻:5D張量,形狀為 (samples, frames, height, width, channels) 或 (samples,frames, channels, height, width)視頻數(shù)據(jù)是現(xiàn)實(shí)生活中需要用到 5D 張量的少數(shù)數(shù)據(jù)類型之一。視頻可以看作一系列幀,每一幀都是一張彩色圖像。由于每一幀都可以保存在一個(gè)形狀為 (height, width, color_depth) 的 3D 張量中,因此一系列幀可以保存在一個(gè)形狀為 (frames, height, width,color_depth) 的 4D 張量中,而不同視頻組成的批量則可以保存在一個(gè) 5D 張量中,其形狀為(samples, frames, height, width, color_depth) 。 舉個(gè)例子,一個(gè)以每秒 4 幀采樣的 60 秒 YouTube 視頻片段,視頻尺寸為 144×256,這個(gè)視頻共有 240 幀。4 個(gè)這樣的視頻片段組成的批量將保存在形狀為 (4, 240, 144, 256, 3)的張量中。總共有 106 168 320 個(gè)值!如果張量的數(shù)據(jù)類型( dtype )是 float32 ,每個(gè)值都是32 位,那么這個(gè)張量共有 405MB。好大!你在現(xiàn)實(shí)生活中遇到的視頻要小得多,因?yàn)樗鼈儾灰詅loat32 格式存儲(chǔ),而且通常被大大壓縮,比如 MPEG 格式。 廣播廣播(Broadcast)是 numpy 對(duì)不同形狀(shape)的數(shù)組進(jìn)行數(shù)值計(jì)算的方式, 對(duì)數(shù)組的算術(shù)運(yùn)算通常在相應(yīng)的元素上進(jìn)行。 import numpy as np'''如果兩個(gè)數(shù)組 a 和 b 形狀相同,即滿足 a.shape == b.shape,那么 a*b 的結(jié)果就是 a 與 b 數(shù)組對(duì)應(yīng)位相乘。這要求維數(shù)相同,且各維度的長(zhǎng)度相同。'''a = np.array([1, 2, 3, 4])b = np.array([10, 20, 30, 40])c = a * bprint(c) # [ 10 40 90 160]'''當(dāng)運(yùn)算中的 2 個(gè)數(shù)組的形狀不同時(shí),numpy 將自動(dòng)觸發(fā)廣播機(jī)制。如:'''a = np.array([[0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]])b = np.array([0, 1, 2])print(a + b)print('\n')'''4x3 的二維數(shù)組與長(zhǎng)為 3 的一維數(shù)組相加,等效于把數(shù)組 b 在二維上重復(fù) 4 次再運(yùn)算:'''a = np.array([[0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]])b = np.array([0, 1, 2])bb = np.tile(b, (4, 1)) # 重復(fù) b 的各個(gè)維度, 假設(shè)reps的維度為d,那么新數(shù)組的維度為max(d,A.ndim)print(bb)print(a + bb) 如果兩個(gè) Tensor 的形狀的長(zhǎng)度不一致,會(huì)在較小長(zhǎng)度的形狀矩陣前部添加 1,直到兩個(gè) Tensor 的形狀長(zhǎng)度相等。 import numpy as np '''如果兩個(gè) Tensor 的形狀的長(zhǎng)度不一致,會(huì)在較小長(zhǎng)度的形狀矩陣前部添加 1,直到兩個(gè) Tensor 的形狀長(zhǎng)度相等。保證兩個(gè) Tensor 形狀相等之后,每個(gè)維度上的結(jié)果維度就是當(dāng)前維度上的較大值。'''x = np.ones([2, 1, 4])y = np.ones((3, 1))print('x => ', x)print('y => ', y)print('x+y => ', x + y) 廣播的規(guī)則:
簡(jiǎn)單理解:對(duì)兩個(gè)數(shù)組,分別比較他們的每一個(gè)維度(若其中一個(gè)數(shù)組沒有當(dāng)前維度則忽略),滿足:
NumPy 應(yīng)用NumPy 通常與 SciPy(Scientific Python)和 Matplotlib(繪圖庫)一起使用, 這種組合廣泛用于替代 MatLab,是一個(gè)強(qiáng)大的科學(xué)計(jì)算環(huán)境,有助于我們通過 Python 學(xué)習(xí)數(shù)據(jù)科學(xué)或者機(jī)器學(xué)習(xí)。 切片和索引arr[x][y] = arr[x,y] 兩種表達(dá)方式 import numpy as nparr = np.arange(21) # arange() 函數(shù)創(chuàng)建 ndarray 對(duì)象# arr = arr.reshape(3, 7)arr.shape = (3, 7)'''[[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]'''print(arr)print('\n')'''arr[x][y] = arr[x,y] 兩種表達(dá)方式冒號(hào) : 的解釋:如果只放置一個(gè)參數(shù),如 [2],將返回與該索引相對(duì)應(yīng)的單個(gè)元素。如 [2:],表示從該索引開始以后的所有項(xiàng)都將被提取。如果使用了兩個(gè)參數(shù),如 [2:7],那么則提取兩個(gè)索引(不包括停止索引)之間的項(xiàng)。'''print('arr[1:2] =>', arr[1:2]) # 【1~2] 行,右側(cè)不包含,列全部顯示 => [[ 7 8 9 10 11 12 13]]print('arr[1:] =>', arr[1:]) # 1 行開始,剩下的全部顯示,列全部顯示 => [[ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]print('arr[:2] =>', arr[:2]) # 取前面兩行數(shù)據(jù) [[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13]]print('arr[2][1:6:2] =>', arr[2][1:6:2]) # start:stop:step => 第2行,1~6列,步長(zhǎng)2(默認(rèn)為1) [15 17 19]print('arr[2, 1:6:2] =>', arr[2, 1:6:2]) # start:stop:step => 第2行,1~6列,步長(zhǎng)2(默認(rèn)為1) [15 17 19]print('arr[:2, 1:6:2] =>', arr[:2, 1:6:2]) # start:stop:step => 前2行,1~6列,步長(zhǎng)2(默認(rèn)為1) [[ 1 3 5] [ 8 10 12]]print('\n')'''切片還可以包括省略號(hào) … ,來使選擇元組的長(zhǎng)度與數(shù)組的維度相同。 如果在行位置使用省略號(hào),它將返回包含行中元素的 ndarray。'''print('arr[1] => ', arr[1]) # 1行,所有列數(shù)據(jù) [ 7 8 9 10 11 12 13]print('arr[1, ...] => ', arr[1, ...]) # 1行,所有列數(shù)據(jù) [ 7 8 9 10 11 12 13]print('arr[..., 3] => ', arr[..., 3]) # 所有行,第3列數(shù)據(jù) [ 3 10 17]print('arr[1] => ', arr[..., 2:]) # 所有行 第3列及剩下的所有元素print('\n') 高級(jí)索引NumPy 中的高級(jí)索引指的是使用整數(shù)數(shù)組、布爾數(shù)組或者其他序列來訪問數(shù)組的元素。相比于基本索引,高級(jí)索引可以訪問到數(shù)組中的任意元素,并且可以用來對(duì)數(shù)組進(jìn)行復(fù)雜的操作和修改。 import numpy as nparr = np.arange(21) # arange() 函數(shù)創(chuàng)建 ndarray 對(duì)象# arr = arr.reshape(3, 7)arr.shape = (3, 7)'''[[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]'''print(arr)print('\n')'''高級(jí)索引'''# 整數(shù)數(shù)組索引是指使用一個(gè)數(shù)組來訪問另一個(gè)數(shù)組的元素。這個(gè)數(shù)組中的每個(gè)元素都是目標(biāo)數(shù)組中某個(gè)維度上的索引值。print('arr[[0, 1, 2], [2, 1, 3]] => ', arr[[0, 1, 2], [2, 1, 3]]) # [0,2]、【1,1】、[2,3] => [ 2 8 17]rows = np.array([[0, 1], [2, 1], [1, 0]])cols = np.array([[2, 1], [3, 2], [0, 2]])'''0,2 1,12,3 1,21,0 0,2'''print('arr[rows, cols] => ', arr[rows, cols]) # [[ 2 8] [17 9] [7 2]]print('\n')'''可以借助切片 : 或 … 與索引數(shù)組組合。'''print('arr[1:3, 1:4] => ', arr[1:3, 1:4]) # [[ 8 9 10] [15 16 17]]print('arr[1:3, [1, 4]] => ', arr[1:3, [1, 4]]) # [[ 8 11] [15 18]]'''[[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]'''print('arr[..., 1:] => ', arr[..., 1:]) # [[ 1 2 3 4 5 6] [ 8 9 10 11 12 13] [15 16 17 18 19 20]] 布爾索引我們可以通過一個(gè)布爾數(shù)組來索引目標(biāo)數(shù)組。 import numpy as nparr = np.arange(21) # arange() 函數(shù)創(chuàng)建 ndarray 對(duì)象# arr = arr.reshape(3, 7)arr.shape = (3, 7)'''[[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]'''print(arr)print('\n')'''獲取大于 5 的元素'''print('arr[arr > 5]', arr[arr > 5]) # [ 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]'''~(取補(bǔ)運(yùn)算符)來過濾NaN。'''arr = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])print('arr[~np.isnan(a)]', arr[~np.isnan(arr)]) # [1. 2. 3. 4. 5.]'''從數(shù)組中過濾掉非復(fù)數(shù)元素。'''arr = np.array([1, 2 + 6j, 5, 3.5 + 5j])print('arr[np.iscomplex(arr)]', arr[np.iscomplex(arr)]) # [2. +6.j 3.5+5.j] 花式索引花式索引指的是利用整數(shù)數(shù)組進(jìn)行索引。 一維數(shù)組一維數(shù)組只有一個(gè)軸 axis = 0,所以一維數(shù)組就在 axis = 0 這個(gè)軸上取值: import numpy as npx = np.arange(9) # [0 1 2 3 4 5 6 7 8]print(x)# 一維數(shù)組讀取指定下標(biāo)對(duì)應(yīng)的元素print('-------讀取下標(biāo)對(duì)應(yīng)的元素-------')x2 = x[[0, 6]] # 使用花式索引print(x2) # [0 6]print(x2[0]) # 0print(x2[1]) # 6 二維數(shù)組import numpy as nparr = np.arange(21) # arange() 函數(shù)創(chuàng)建 ndarray 對(duì)象# arr = arr.reshape(3, 7)arr.shape = (3, 7)'''[[ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13] [14 15 16 17 18 19 20]]'''print(arr)print('\n')print('arr[1, [0, 2]] => ', arr[1, [0, 2]]) # [7 9]print('arr[[0, 2], 1] => ', arr[[0, 2], 1]) # [ 1 15]print('arr[[0, 2]] => ', arr[[0, 2]]) # [[ 0 1 2 3 4 5 6] [14 15 16 17 18 19 20]]# 傳入順序索引數(shù)組print('arr[[2,0,1]] => ', arr[[2, 0, 1]]) # [[14 15 16 17 18 19 20] [ 0 1 2 3 4 5 6] [ 7 8 9 10 11 12 13]]# 傳入倒序索引數(shù)組print('arr[[-2,-0,-1]] => ', arr[[-2, -0, -1]]) # [[ 7 8 9 10 11 12 13] [ 0 1 2 3 4 5 6] [14 15 16 17 18 19 20]]# 傳入多個(gè)索引數(shù)組(要使用 np.ix_)'''np.ix_ 函數(shù)就是輸入兩個(gè)數(shù)組,產(chǎn)生笛卡爾積的映射關(guān)系。笛卡爾乘積是指在數(shù)學(xué)中,兩個(gè)集合 X 和 Y 的笛卡爾積(Cartesian product),又稱直積,表示為 X×Y,第一個(gè)對(duì)象是X的成員而第二個(gè)對(duì)象是 Y 的所有可能有序?qū)Φ钠渲幸粋€(gè)成員。例如 A={a,b}, B={0,1,2},則:A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}[1, 0, 2, 1], [0, 3, 1, 2] => (1,0),(1,3),(1,1),(1,2),(0,0),(0,3),(0,1),(0,2)....'''print('arr[np.ix_([1,5,7,2],[0,3,1,2])] => ', arr[np.ix_([1, 0, 2, 1], [0, 3, 1, 2])]) # [[ 7 10 8 9] [ 0 3 1 2] [14 17 15 16] [7 10 8 9]] 相關(guān)鏈接NumPy 官網(wǎng) http://www./ 結(jié)語喜歡人工智能的小伙伴記得關(guān)注點(diǎn)贊哦~ |
|