網站首頁 編程語言 正文
1、Numpy概述
1.1 概念
Python本身含有列表和數組,但對于大數據來說,這些結構是有很多不足的。由于列表的元素可以是任何對象,因此列表中所保存的是對象的指針。對于數值運算來說這種 結構比較浪費內存和CPU資源。至于數組對象,它可以直接保存 數值,和C語言的一維數組比較類似。但是由于它不支持多維,在上面的函數也不多,因此也不適合做數值運算。Numpy提供了兩種基本的對象:ndarray(N-dimensional Array Object)和 ufunc(Universal Function Object)。ndarray是存儲單一數據類型的多維數組,而ufunc則是能夠對數組進行處理的函數。
1.2 功能
- 創建n維數組(矩陣)
- 對數組進行函數運算,使用函數計算十分快速,節省了大量的時間,且不需要編寫循環,十分方便
- 數值積分、線性代數運算、傅里葉變換
- ndarray快速節省空間的多維數組,提供數組化的算術運算和高級的 廣播功能。
1.3 對象
- NumPy中的核心對象是ndarray
- ndarray可以看成數組,存放同類元素
- NumPy里面所有的函數都是圍繞ndarray展開的
ndarray 內部由以下內容組成:
? 一個指向數據(內存或內存映射文件中的一塊數據)的指針。
? 數據類型或 dtype,描述在數組中的固定大小值的格子。
? 一個表示數組形狀(shape)的元組,表示各維度大小的元組。形狀為(row×col)
1.4 數據類型
numpy 支持的數據類型比 Python 內置的類型要多很多,基本上可以和C語言的數據類型對應上主要包括int8、int16、int32、int64、uint8、uint16、uint32、uint64、float16、float32、float64
1.5 數組屬性
屬性 | 說明 |
---|---|
ndarray.ndim | 秩,即軸的數量或維度的數量 |
ndarray.shape | 數組的維度(n×m),對于矩陣,n 行 m 列 |
ndarray.size | 數組元素的總個數,相當于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 對象的元素類型 |
ndarray.itemsize | ndarray 對象中每個元素的大小,以字節為單位 |
ndarray.flags | ndarray 對象的內存信息 |
ndarray.real | ndarray元素的實部 |
ndarray.imag | ndarray元素的虛部 |
ndarray.data | 包含實際數組元素的緩沖區,由于一般通過數組的索引獲取元素,所以通常不需要使用這個屬性。 |
2、Numpy數組操作
2.1 Numpy創建
2.1.1 利用列表生成數組
import numpy as np lst = [1, 2, 3, 4] nd1 = np.array(lst) print(nd1, type(nd1)) #[1 2 3 4]
2.1.2 利用random模塊生成數組
下面是random模塊的一些常用函數
::: hljs-center
使用如下:
import numpy as np #0到1標準正態分布 arr1 = np.random.randn(3, 3) #0到1均勻分布 arr2 = np.random.rand(3, 3) #均勻分布的隨機數(浮點數),前兩個參數表示隨機數的范圍,第三個表示生成隨機數的個數 arr3 = np.random.uniform(0, 10, 2) #均勻分布的隨機數(整數),前兩個參數表示隨機數的范圍,第三個表示生成隨機數的個數 arr4 = np.random.randint(0, 10, 3) print(f'arr1 : {arr1}\narr2 : {arr2}\narr3 : {arr3}\narr4 : {arr4}') out : # arr1 : [[-0.31637952 -0.08258995 1.43866984] # [-0.11216775 0.43881134 0.11745847] # [-1.1770306 -0.97657465 2.2368878 ]] # arr2 : [[0.16350611 0.4467384 0.9465067 ] # [0.1882318 0.40261184 0.93577701] # [0.56243911 0.69179631 0.83407725]] # arr3 : [4.41402883 6.03259052] # arr4 : [9 7 7]
如果想使每次生成的數據相同,可以指定一個隨機種子
import numpy as np np.random.seed(123) arr = np.random.rand(2, 3)#[[0.69646919 0.28613933 0.22685145] [0.55131477 0.71946897 0.42310646]] #打亂數組 np.random.shuffle(arr)#[[0.55131477 0.71946897 0.42310646] [0.69646919 0.28613933 0.22685145]]
2.1.3 創建特定形狀數組
主要有如下幾種:
import numpy as np #未初始化的數組 arr1 = np.empty((2,3)) #數組元素以 0 來填充 arr2 = np.zeros((2, 3)) #數組元素以 1 來填充 arr3 = np.ones((2, 3)) #數組以指定的數來進行填充,這里舉例3 arr4 = np.full((2, 3), 3) #生成單位,對角線上元素為 1,其他為0 arr5 = np.eye(2) #二維矩陣輸出矩陣對角線的元素,一維矩陣形成一個以一維數組為對角線元素的矩陣 arr6 = np.diag(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
在創建給定長度的等差數列時,要注意的是np.linspace形成的數組一定包括范圍的首位兩個元素,則步長為(end - start) / (length - 1)。而np.arange是自己指定的步長(默認為1)也就意味著形成的數組不一定包括末尾數
arr7 = np.linspace(0, 1, 4) #out : array([0. , 0.33333333, 0.66666667, 1. ]) arr8 = np.arange(0, 9, 2) #out : array([0, 2, 4, 6, 8])
2.2 索引和切片
Numpy可以通過索引或切片來訪問和修改,與 Python 中 list 的切片操作一樣,設置start, stop 及 step 參數。
2.2.1 元素表示
Numpy數組的下標表示與list是一樣的,對于矩陣來說,要注意中括號里要用逗號將行和列的表示進行分隔。基本的表示方法如下圖,左邊為表達式,右邊為表達式獲取的元 素。注意,不同的邊界,表示不同的表達式。
例子:
a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
a[0] : 指的是第一行
a[1, 2] 或者 a[1][2] : 全下標定位單個元素,在a中表示7這個元素
2.2.2 切片表示
若a = np.arange(10),b = a[2 : 7 : 2]則表示從索引 2 開始到索引 7 停止,間隔為 2,即b為[2, 4, 6]。此外也可以通過切片操作來對元素進行修改,如:
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a[0 , 1 : 3] = 100, 101#a[0 , 1 : 3]表示第一行的第二列和第二列即[2, 3] a #out : array([[ 1, 100, 101], [ 4, 5, 6], [ 7, 8, 9]])
2.2.3 多維數組的切片
NumPy的多維數組和一維數組類似。多維數組有多個軸。從內到外分別是第0軸,第1軸,第2軸......切片后的數據與切片前的數據共享原數組的儲存空間
當然,切片操作是針對我們想要獲取的數據是連續的,如果我們想要獲取離散數據就不能使用切片的方法,再者就是我們不能一個一個來進行提取,Numpy有一種很方便的方法可以獲得離散數據。即下面
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) rows = np.array( [ [0,0],[3,3] ] ) #表示第1、4行 cols = np.array( [ [0,2],[0,2] ] ) #表示第1、3列 y = x[rows,cols] y # out : array([[ 0, 2], [ 9, 11]])
2.2.4 布爾索引
顧名思義,通過布爾運算(如:比較運算符)來獲取符合指定條件的元素的數組。
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) print(x[x > 5]) # out : [ 6 7 8 9 10 11] b = x > 5 b # 打印布爾運算的結果
2.2.5 元素查找定位
Numpy庫中提供了where函數來查找滿足條件元素的索引,表示如下:
- np.where(condition, x, y): 滿足條件(condition),輸出x,不滿足輸出y
- np.where(condition): 輸出滿足條件 (即非0) 元素的坐標
a = np.array([2,4,6,8,10,3]).reshape(2,3) c = np.where(a > 5) # 返回索引 out : (array([0, 1, 1], dtype=int64), array([2, 0, 1], dtype=int64)) a[c] # 獲得元素
2.2.6 元素刪除
np.delete(arr, obj, axis=None)
- 第一個參數:要處理的矩陣,
- 第二個參數,處理的位置,下標
- 第三個參數,0表示按照行刪除,1表示按照列刪除,默認為0
- 返回值為刪除后的剩余元素構成的矩陣
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]) np.delete(arr, [1], 0) # 表示刪除第二行
2.3 Numpy數組的拼接和分割
2.3.1 拼接
下面的圖列舉了常見的用于數組或向量 合并的方法。
說明:
- append、concatenate以及stack都有一個axis參數,用于控制數組的合 并方式是按行還是按列。
- 對于append和concatenate,待合并的數組必須有相同的行數或列數
- stack、hstack、dstack,要求待合并的數組必須具有相同的形狀
a = np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) np.hstack((a,b)) #等效于 np.concatenate((a,b),axis = 1) # out : array([[1, 2, 5, 6], [3, 4, 7, 8]]) a = np.array([[1, 2], [3, 4]]) b = np.array([[5, 6], [7, 8]]) np.vstack((a,b)) #等價于 np.concatenate((a,b),axis = 0) # out : array([[1, 2], [3, 4], [5, 6], [7, 8]])
2.3.2 分割
- 水平分割:np.split(arr,n,axis=1) 或 np.hsplit(arr,n):按列分成n份。返回一個list
- 垂直分割:np.split(arr,n,axis=0) 或 np.vsplit(arr,n):按行分成n份,返回一個list
x = np.arange(12).reshape(3, 4) np.split(x, 3) # out : [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])] y = np.arange(9).reshape(1, 9) np.split(y, 3, axis = 1) # out : [array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]
2.4 維度變換
在機器學習以及深度學習的任務中,通常需要將處理好的數據以模型能 接收的格式輸入給模型,然后由模型通過一系列的運算,最終返回一個處理 結果。然而,由于不同模型所接收的輸入格式不一樣,往往需要先對其進行 一系列的變形和運算,從而將數據處理成符合模型要求的格式。在矩陣或者 數組的運算中,經常會遇到需要把多個向量或矩陣按某軸方向合并,或展平 (如在卷積或循環神經網絡中,在全連接層之前,需要把矩陣展平)的情 況。下面介紹幾種常用的數據變形方法。
?
1)?reshape??不改變原數組元素,返回一個新的shape維度的數組(維度變換)
x = np.arange(12).reshape(3, 4) x # out : array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]) # 指定維度時可以只指定行數或列數, 其他用 -1 代替 x.reshape(3, -1) # out : array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
2)?resize??改變向量的維度(修改向量本身):
arr =np.arange(10) print(arr) # out : [0 1 2 3 4 5 6 7 8 9] arr.resize(2, 5) # 將向量 arr 維度變換為2行5列 print(arr) # out : [[0 1 2 3 4], [5 6 7 8 9]]
3)?T??轉置
arr = np.arange(8).reshape(2, 4) arr.shape # out : (2, 4) arr.T.shape # out : (4, 2)
4)?ravel??向量展平
arr = np.arange(8).reshape(2, 4) arr.ravel() # out : array([0, 1, 2, 3, 4, 5, 6, 7])
5)?flatten??把矩陣轉換為向量,這種需求經常出現在卷積網絡與全連接層之間。
arr = np.arange(8).reshape(2, 4) arr.flatten() # out : array([0, 1, 2, 3, 4, 5, 6, 7])
6)?squeeze??這是一個主要用來降維的函數,把矩陣中含1的維度去掉
arr = np.arange(8).reshape(2, 4, 1) arr.shape # out : (2, 4, 1) arr.squeeze().shape # out : (2, 4)
7)?transpose??對高維矩陣進行軸對換,這個在深度學習中經常使用,比如把圖片中表 示顏色順序的RGB改為GBR。
arr = np.arange(12).reshape(2, 6, 1) arr.shape # out : (2, 6, 1) arr.transpose(1, 2, 0).shape # out : (6, 1, 2)
拓展8)?swapaxes??將兩個維度調換, 就是把對應的下標換個位置,類似于transpose
arr = np.arange(20).reshape(4, 5) arr.swapaxes(1, 0)
2.5 Numpy數值計算
2.5.1 通用函數對象(ufunc)
ufunc是universal function的簡稱,種能對數組每個元素進行運算的函數。NumPy的許多ufunc函數都是用C語言實現的,因此它們的運算速度非常快。下圖是在數據批量處過程中較為常用的幾個函數
使用的格式基本如下:np.函數名(數組, 指定計算的維度(默認為0)),如:
a = np.array([[6, 3, 7, 4, 6], [9, 2, 6, 7, 4], [3, 7, 7, 2, 5], [4, 1, 7, 5, 1]]) np.sum(a, axis = 0) # out : array([22, 13, 27, 18, 16]) np.sum(a, axis = 1)# out : array([26, 28, 24, 18]
其余函數使用過程均可參考上述求和過程。下面繼續介紹一下數組的排序問題。主要使用函數有np.min,np.max,np.median。
arr = np.array([[10, 11, 12], [13, 14, 15]]) np.min(arr, axis = 0) # out : array([10, 11, 12]) 按行求最小值,即列不變,行變 np.min(arr, axis = 1) # out : array([10, 13]) 按列求最小值,即行不變,列變
我們可以通過np.argmin,np.argmax獲得相對應的最小值、最大值的下標
arr = np.array([[10, 14, 12], [13, 11, 15]]) np.argmin(arr, axis = 0) # out : array([0, 1, 0], dtype=int64) 按行求最小值,即列不變,行變 np.argmin(arr, axis = 1) # out : array([0, 1], dtype=int64) 按列求最小值,即行不變,列變
使用np.sort和np.argsor進行排序并排序后的下標
arr = np.array([1, 3, 5, 2, 4]) np.sort(arr) # out : array([1, 2, 3, 4, 5]) np.argsort(arr) # out : array([0, 3, 1, 4, 2], dtype=int64)
2.5.2 矩陣運算
1) 對應元素相乘??對應元素相乘(Element-Wise Product)是兩個矩陣中對應元素乘積。 np.multiply函數用于數組或矩陣對應元素相乘,輸出與相乘數組或矩陣的大 小一致。
a = np.array([[1,0],[0,1]]) b = np.array([[4,1],[2,2]]) np.multiply(a, b) # 等效于a * b,out : array([[4, 0], [0, 2]])
計算過程如下圖:
2) 點積??點積運算(Dot Product)又稱為內積,在Numpy用np.dot或者np.matmul表示
a = np.array([[1,0],[0,1]]) b = np.array([[4,1],[2,2]]) np.dot(a, b) # 等效于np.matmul(a, b) out : array([[4, 1], [2, 2]])
計算過程如下圖:
3) 行列式??計算行列式的值
arr = np.array([[1,2], [3,4]]) np.linalg.det(arr) # out : -2.0000000000000004
4) 求逆
arr = np.array([[1,2], [3,4]]) np.linalg.inv(arr) # out : array([[-2. , 1. ], [ 1.5, -0.5]])
5) 特征值和特征向量
A = np.random.randint(-10,10,(4,4)) C = np.dot(A.T, A) vals, vecs = np.linalg.eig(C) print(f'特征值 : {vals}, 特征向量 : {vecs}') out : 特征值 : [395.26566729 358.52489695 44.41465068 52.79478508] 特征向量 : [[ 0.30221599 0.64309202 -0.64757004 -0.27522935] [ 0.87819925 -0.03518532 0.18871425 0.43808105] [-0.35779498 0.26192443 -0.27010759 0.85464626] [ 0.09702746 -0.71874212 -0.68708214 0.04374437]]
2.6 插值運算
這個過程其實就是我們在數學中已知一個函數,然后給出x值,讓你根據這個函數求對應的y值,一般在曲線平滑處理中有較多的使用在Numpy中由numpy.interp(x, xp, fp, left=None, right=None, period=None)表示
- x - 表示將要計算的插值點x坐標
- xp - 表示已有的xp數組
- fp - 表示對應于已有的xp數組的值
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2 * np.pi, 10) y = np.sin(x) xvals = np.linspace(0, 2 * np.pi, 10000) yinterp = np.interp(xvals, x, y) plt.plot(x, y, 'r-', xvals, yinterp, 'b-') plt.show()
::: hljs-center
2.7 曲線擬合
我們在數學建模過程中得到我們的數據之后,如果我們想要使用某個函數去描述數據的規律,這個過程其實就在曲線擬合的過程,這里只介紹最簡單的一種擬合方式。Numpy中由numpy.polyfit(x, y, deg)表示
- x為待擬合的x坐標
- y為待擬合的y坐標
- deg為擬合自由度,即多項式的最高次冪
import matplotlib.pyplot as plt import numpy as np x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0]) y = np.array([0.0, 0.8, 0.9, 0.1, -0.8, -1.0]) #得到多項式的系數 z = np.polyfit(x, y, 3) z2 = np.polyfit(x, y, 5) #得到多項式函數 f = np.poly1d(z) f2 = np.poly1d(z2) #用兩個函數進行擬合 xval = np.linspace(0, 10, 50) yval1 = f(xval) yval2 = f2(xval) #作圖 plt.plot(xval, yval1, 'r--o', xval, yval2, 'b-o') plt.legend(['The deg is 3', 'The deg is 5']) plt.show() print(f) # out : 0.08704 x^3 - 0.8135 x^2 + 1.693 x - 0.03968 print(f2) # out : -0.008333 x^5 + 0.125 x^4 - 0.575 x^3 + 0.625 x^2 + 0.6333 x - 1.74e-14
::: hljs-center
由圖能夠看出,3和5自由度的函數在前面的函數曲線基本是重合的,但是約在7左右開始朝著相反方向進行變化,因此擬合函數的自由度對效果的影響是非常大的,找到一個合適的自由度至關重要。
3 Numpy IO操作
1) 保存數組??保存一個數組到一個二進制的文件中,保存格式是.npy,Numpy中由np.save(file, array)表示。
2) 讀取文件??arr = numpy.load(file): 讀取npy 文件到內存
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) #保存數據 np.save('test.npy', arr) #下載數據 np.load('test.npy') # out : array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
拓展??保存到文本文件
- np.savetxt(fname, X, fmt=‘%.18e’, delimiter=‘ ‘)
- arr = numpy.loadtxt(fname, delimiter=None)
參考《Python深度學習基于PyTorch》 吳茂貴
原文鏈接:https://www.cfanz.cn/resource/detail/oXPVRzYgAqyDz
相關推薦
- 2023-02-12 python中使用docx模塊處理word文檔_python
- 2022-06-07 FreeRTOS操作系統的配置示例解析_操作系統
- 2024-02-25 前端顯示的日期時間與數據庫日期時間不一致
- 2021-12-16 方案缺陷-HAProxy + Sentinel +redis
- 2022-12-14 Jetpack?Compose?DropdownMenu手指跟隨點擊顯示_Android
- 2021-11-06 Docker下部署lnmp詳細步驟_docker
- 2022-05-28 Redis如何使用樂觀鎖(CAS)保證數據一致性_Redis
- 2022-07-07 Python數據分析之?Matplotlib?3D圖詳情_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支