收藏 | 深度學(xué)習(xí)之Numpy基礎(chǔ)入門教程!
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
本文轉(zhuǎn)自|計算機視覺聯(lián)盟
Numpy (Numerical Python)提供了兩種基本對象:
ndarray(N-dimensional Array Object),存儲單一的數(shù)據(jù)類型的多維數(shù)組
ufunc(Universal Function Object),能夠?qū)?shù)組進(jìn)行處理的函數(shù)
Numpy 的主要特點:
ndarray,快速節(jié)省空間的多維數(shù)組
使用標(biāo)準(zhǔn)數(shù)學(xué)函數(shù)對整個數(shù)組的數(shù)據(jù)進(jìn)行快速運算,不需要編寫循環(huán)
讀取、寫入磁盤上的陣列數(shù)據(jù)和操作存儲器影像文件的工具
線性代數(shù)、隨機數(shù)生成和傅里葉變換的能力
集成C、C++、Fortran代碼
import numpy as np
如何查看函數(shù)的幫助指令
np.add?
1.1.1 從已有數(shù)據(jù)中創(chuàng)建數(shù)組
(1)將列表轉(zhuǎn)換成ndarray
import numpy as np
1st1 = [1.1, 2.2, 3, 4, 5, 6.6]
nd1 = np.array(1st1)
print(nd1)
# [1.1, 2.2, 3, 4, 5, 6.6]
print(type(nd1))
# <class 'numpy.ndarray'>
(2)嵌套列表可轉(zhuǎn)換為多維ndarray
import numpy as np
1st2 = [[1.1, 2.2, 3, 4, 5, 6.6], [1,2,3,4]]
nd2 = np.array(1st2)
print(nd2)
# [[1.1, 2.2, 3, 4, 5, 6.6]
# [1,2,3,4]]
# [1.1, 2.2, 3, 4, 5, 6.6]
print(type(nd2))
# <class 'numpy.ndarray'>
1.1.2 利用random模塊生成數(shù)組
np.random模塊常用函數(shù):
* np.random.random,生成0-1之間隨機數(shù)
* np.random.uniform,生成均勻分布的隨機數(shù)
* np.random.randn,生政標(biāo)準(zhǔn)正太分布的隨機數(shù)
* np.random.randint,生成隨機的證書
* np.random.normal,生成正態(tài)分布
* np.random.shuffle,隨機打亂順序
* np.random.seed,設(shè)置隨機數(shù)粽子
* random_sample,生成隨機的浮點數(shù)
具體使用
import numpy as np
nd3 = np.random.random([3,3])
print(nd3)
#[[]
# []
# []]
print("nd3的形狀為:",nd3.shape)
# nd3的形狀為:(3,3)
每次生成同一份數(shù)據(jù),可以指定一個隨機種子,使用shuffle函數(shù)打亂生成的隨機數(shù)
import numpy as np
np.random.seed(123)
nd4 = np.random.randn(2,3)
print(nd4)
np.random.shuffle(nd4)
print("隨機打亂后的數(shù)據(jù):")
print(nd4)
print(type(nd4))
1.1.3 創(chuàng)建特定形狀的多維數(shù)組
Numpy數(shù)組創(chuàng)建函數(shù)
* np.zeros((3,4)) 創(chuàng)建3x4的元素全是0的數(shù)組
* np.ones((3,4)) 創(chuàng)建3x4的元素全是1的數(shù)組
* np.empty((2,3)) 創(chuàng)建2x3的空數(shù)組
* np.zeros_like(abc) 創(chuàng)建與abc相同緯度的全是0的數(shù)組
* np.ones_like(abc) 創(chuàng)建與abc相同緯度的全是1的數(shù)組
* np.empty_like(abc) 創(chuàng)建與abc相同緯度的空數(shù)組
* np.eye(5) 創(chuàng)建一個5x5的矩陣,對角線是1,其余是0
* np.full((3,5),666) 創(chuàng)建3x5的元素全是666的數(shù)組
有時候還可以把數(shù)據(jù)保存起來方便后續(xù)使用
import numpy as np
nd9 = np.random.random([5,5])
np.savetxt(X=nd9, fname='./test1.txt')
nd10 = np.loadtxt('./test1.txt')
print(nd10)
1.1.4 利用arange、linspace函數(shù)生成數(shù)組
arange
arange([start,] stop[,step,], dtype=None)
start、stop指定范圍,step設(shè)定步長
start默認(rèn)是0開始。
import numpy as np
print(np.arange(10))
# [0 1 2 3 4 5 6 7 8 9]
print(np.arange(0,10))
# [0 1 2 3 4 5 6 7 8 9]
print(np.arange(1, 4, 0.5))
# [1 1.5 2 2.5 3 3.5]
print(np.arange(9,-1,-1))
# [9 8 7 6 5 4 3 2 1 0]
linspace
np.linspace(start, stop, num=50, endpoint=True, restep=False, dtype=None)
默認(rèn)線性等分,默認(rèn)等分為50
import numpy as np
print(np.linspace(0, 1, 10))
#[0 0.11111 0.22222 ...... 1]
# 這里沒有像生成0.1,0.2這樣規(guī)則的數(shù)據(jù),是因為,這里需要包含0,1,所以最后除以了9
#(1-0)/0=0.111111,否則需要改起始位置為0.1即可
import numpy as np
np.random.seed(2019)
nd11 = np.random.random([10])
# 獲取指定位置的數(shù)據(jù),比如獲取第5個元素
nd11[4]
# 獲取一段數(shù)據(jù)
nd11[3:7]
# 獲取固定間隔取數(shù),比如每間隔2個取一個
nd11[1:6:2]
# 獲取一個多維數(shù)組的一個區(qū)域內(nèi)的數(shù)據(jù)
nd12 = np.arange(25).reshape([5,5])
nd12[1:3,1:3]
# 獲取一個多維數(shù)組中,數(shù)值在一個值域內(nèi)的數(shù)據(jù)
nd12[(nd12>3)&(nd12<12)]
# 截取指定的行,比如第2,3行
nd12[[1,2]] # 或 nd12[1:3,:]
# 截取指定的列,比如第2,3列
nd12[:,1:3]
random.choice 可以從指定的樣本中隨機抽取數(shù)據(jù)
import numpy as np
from numpy import random as nr
a = np.arange(1,25,dtype=float)
# size指定輸出數(shù)組形狀
c1=nr.choice(a,size=(3,4))
# replace缺省為TUre,即可重復(fù)抽取,F(xiàn)alse就是雖然隨機但是不重復(fù)
c2=nr.choice(a,size=(3,4),replace=False)
# p這個參數(shù),缺省時每個元素的抽取概率相同,否則按照規(guī)則進(jìn)行
c3=nr.choice(a,size(3,4),p=a/np.sum(a))
print("隨機可重復(fù)抽?。?)
print(c1)
print("隨機但不重復(fù)抽取:")
print(c2)
print("隨機但按制度概率抽取:")
print(c3)
1.3.1 對應(yīng)元素相乘(逐元相乘)
np.mutiply用于數(shù)組或者矩陣對應(yīng)元素相乘
numpy.multiply(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj])
舉例子A與B矩陣相乘
A = np.array([[1, 2], [-1, 4]])
B = np.array([[2, 0], [3, 4]])
A*B
# 或者
numpy.multiply(A,B)
# array([[2, 0],
[-3, 16])
Numpy數(shù)組不僅可以與數(shù)組進(jìn)行相乘,還可以進(jìn)行標(biāo)量運算
print(A*2.0)
print(A/2.0)
數(shù)組通過一些激活函數(shù)后,輸出與輸入的形狀一致
X = np.random.rand(2,3)
def softmoid(x):
return 1/(1+np.exp(-x))
def relu(x):
return np.maximum(0,x)
def softmax(x):
return np.exp(x)/np.sum(np.exp(x))
print("輸入?yún)?shù)X的形狀:", X.shape)
print("激活函數(shù)softmoid輸出形狀:", softmoid(X).shape)
print("激活函數(shù)relu輸出形狀:", relu(X).shape)
print("激活函數(shù)softmax輸出形狀:", softmax(X).shape)
1.3.2 點積運算(矩陣乘法)
np.dot
numpy.dot(a, b, out=None)
這就是真正的矩陣乘法
X1=np.array([[1,2],[3,4]])
X2=np.array([[5,6,7],[8,9,10]])
X3=np.dot(X1,X2)
print(X3)
# 下標(biāo)2x2*2x3=2x3
1.4.1 更改數(shù)組的形狀
Numpy中改變向量的一些函數(shù)
* arr.reshape 重新將維度改變,不改變向量本身
* arr.resize 重新將維度改變,修改向量本身
* arr.T 轉(zhuǎn)置
* arr.ravel 對向量展開成1維數(shù)組,不會產(chǎn)生原數(shù)組的副本
* arr.flatten 對向量展開成1維數(shù)組,會返回原數(shù)組的副本
* arr.squeeze 只能對1維降維,對多維不報錯但是沒有用
* arr.transpose 對高緯矩陣進(jìn)行軸對換reshape(不修改向量本身)
import numpy as np
arr = np.arrange(10)
print(arr)
# 變?yōu)?行5列
print(arr.reshape(2,5))
# 指定維度時可以只指定其中一個,剩下用-1代替
print(arr.reshape(5,-1))
print(arr.reshape(-1,2))
resize(修改向量本身)
import numpy as np
arr = np.arrage(10)
print(arr)
arr.resize(2,5)
print(arr)
T
import numpy as np
arr = np.arrange(12).reshape(3,4)
print(arr)
print(arr.T)
ravel 向量展平
import numpy as np
arr = np.arange(6).reshape(2,-1)
print(arr)
# 按照列優(yōu)秀展平
print(arr.ravel('F'))
# 按照行優(yōu)先,展平
print(arr.ravel())
flatten 矩陣轉(zhuǎn)換為向量
常用在卷積網(wǎng)絡(luò)與全連接層之間
import numpy as np
a = np.floor(10*np.random.random((3,4)))
print(a)
print(a.flatten())
squeeze 降維,含1的維度去掉
import numpy as np
arr = np.arange(3).reshape(3,1)
print(arr.shape)
print(arr.squeeze().shape)
arr1 = np.arange(6).reshape(3,1,2,1)
print(arr1.shape)
print(arr1.squeeze().shape)
#(3, 1)
#(3,)
#(3, 1, 2, 1)
#(3, 2)
transpose
實際中經(jīng)常把顏色順序從RGB變?yōu)镚BR就是一個應(yīng)用
import numpy as np
arr2 = np.arange(24).reshape(2,3,4)
print(arr2)
print(arr2.shape)
print(arr2.transpose(0,1,2).shape)
print(arr2.transpose(1,2,0).shape)
print(arr2.transpose(2,1,0).shape)
# 結(jié)果
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
(2, 3, 4)
(2, 3, 4)
(3, 4, 2)
(4, 3, 2)
1.4.2 合并數(shù)組
Numpy數(shù)組合并方法
* np.append 內(nèi)存占用大
* np.concatenate 沒有內(nèi)存問題
* np.stack 沿著新的軸加入一系列數(shù)組
* np.hstack 堆棧數(shù)組垂直順序(行)
* np.vstack (列)
* np.dstack 按順序深入(沿第3維)
* np.vsplit 數(shù)組分解成垂直的多個子數(shù)組列表
append
# 合并一維數(shù)組
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.append(a,b)
print(c)
# [1 2 3 4 5 6]
# 合并多維數(shù)組
import numpy as np
a = np.arange(4).reshape(2,2)
b = np.arange(4).reshape(2,2)
# 按行處理
c = np.append(a,b,axis=0)
print("按行合并后的結(jié)果")
print(c)
print(c.shape)
d = np.append(a,b,axis=1)
print("按列合并后的結(jié)果")
print(d)
print(d.shape)
[[0 1]
[2 3]
[0 1]
[2 3]]
(4,2)
[[0 1 0 1]
[2 3 2 3]]
(2,4)
concatenate
沿著指定軸連接數(shù)組或者矩陣
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([5,6])
c = np.concatenate((a,b), axis=0) # 按照行加
print(c)
d = np.concatenate((a, b.T), axis=1)
print(d)
[[1 2]
[3 4]
[5 6]]
[[1 2 5]
[3 4 6]]
stack
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(np.stack((a,b), axis=0))
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
如何把大數(shù)據(jù)拆分成多個批次呢?
拿到數(shù)據(jù)集
隨機打亂數(shù)據(jù)
定義批大小
批處理數(shù)據(jù)集
import numpy as np
# 生成10000個形狀為2x3的矩陣
data_train = np.random.randn(10000,2,3)
print(data_train.shape)
#(10000,2,3)
# 打亂這10000條數(shù)據(jù)
np.random.shuffle(data_train)
# 定義批量大小
batch_size = 100
# 進(jìn)行批量處理
for i in range(0,len(data_train),batch_size):
x_batch_sum = np.sum(data_train[i:i+batch_size])
print("第{}批次,該批次數(shù)據(jù)的和:{}".format(i,x_batch_sum))
Numpy提供了兩種基本的對象,ndarray和ufunc對象
ufunc 是universal function的縮寫,對數(shù)組的每個元素進(jìn)行操作的函數(shù),運算速度快一些
常用的函數(shù)
* sqrt 平方根
* sin,cos
* abs
* dot 矩陣計算
* log,log10,log2
* exp
* cumsum,cumproduct 累計求和,累計求積
* sum
* mean 均值
* median 中位數(shù)
* std 標(biāo)準(zhǔn)差
* var 方差
* corrcoef 相關(guān)系數(shù)
1.6.1 math 與numpy函數(shù)性能比較
import time
import math
import numpy as np
x = [i * 0.001 for i in np.arange(1000000)]
start = time.clock()
for i, t in enumerate(x):
x[i] = match.sin(t)
print("math.sin:", time.clock() - start)
x = [i * 0.001 for i in np.arange(1000000)]
x = np.array(x)
start = time.clock()
np.sin(x)
print("numpy.sin:", time.clock() - start)
numpy.sin 比 math.sin 快10倍不止!
1.6.2 循環(huán)與向量運算比較
Numpy庫中的內(nèi)建函數(shù)使用了SIMD指令,比使用循環(huán)速度快很多!
GPU比Numpy更快,但是Numpy不支持GPU,Pytorch支持!
import time
import numpy as np
x1 = np.random.rand(1000000)
x2 = np.random.rand(1000000)
# 循環(huán)使用計算向量點積
tic = time.process_time()
dot = 0
for i in range(len(x1))
dot+=x1[i]*x2[i]
toc = time.process_time()
print ("dot = " + str(dot) + "\n 循環(huán)計算時間為:" + str(1000*(toc-tic)) + "ms")
# 使用numpy函數(shù)計算點積
tic = time.process_time()
dot = 0
dot = np.dot(x1,x2)
toc = time.process_time()
print ("dot = " + str(dot) + "\n Numpy計算時間為:" + str(1000*(toc-tic)) + "ms")
dot = 249895.7424207973
循環(huán)計算時間為:625.0ms
dot = 249895.7424208079
Numpy計算時間為:15.625ms
歸納為以下四條:
讓所有數(shù)組向最長的數(shù)組看齊,不足的部分前面補1,舉列子就是a:2x3x2,b:3x2,那么b:1x3x2
輸出數(shù)組的shape是輸入數(shù)組shape的各個軸上最大值
如果輸入數(shù)組的某個軸和輸出數(shù)組的對應(yīng)軸的長度相同或者某個軸長度為1時,這個數(shù)組能用來被計算,否則出錯
當(dāng)輸入數(shù)組的某個軸的長度為1時,沿此軸運算時都要復(fù)制此軸上的第一組值
import numpy as npA = np.arange(0, 40, 10).reshape(4,1)print(A)B = np.arange(0,3)print(B)print(“A的形狀:{},B的形狀:{}”.format(A.shape,B.shape))C = A+Bprint(“C的形狀:”+ C.shape)print(C)[[ 0][10][20][30]][0 1 2]A的形狀:(4, 1),B的形狀:(3,)C的形狀:(4, 3)[[ 0 1 2][10 11 12][20 21 22][30 31 32]]
好消息,小白學(xué)視覺團(tuán)隊的知識星球開通啦,為了感謝大家的支持與厚愛,團(tuán)隊決定將價值149元的知識星球現(xiàn)時免費加入。各位小伙伴們要抓住機會哦!

交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

