日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python?Numpy庫的超詳細教程_python

作者:做個橙夢 ? 更新時間: 2022-06-07 編程語言

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

欄目分類
最近更新