Numpy学习笔记(下篇)
目錄
- Numpy學(xué)習(xí)筆記(下篇)
- 一、Numpy數(shù)組的合并與分割操作
- 1、合并操作
- 2、分割操作
- 二、Numpy中的矩陣運(yùn)算
- 1、Universal Function
- 2、矩陣運(yùn)算
- 3、向量和矩陣運(yùn)算
- 三、Numpy中的聚合操作
- 四、Numpy中的arg運(yùn)算
- 1、索引操作
- 2、排序和索引使用
- 五、Fancy Indexing
- 六、Numpy.array的比較
- 我是尾巴
Numpy學(xué)習(xí)筆記(下篇)
路漫漫其修遠(yuǎn)兮,吾將上下而求索!Numpy學(xué)習(xí)筆記(上篇)
一、Numpy數(shù)組的合并與分割操作
? 在機(jī)器學(xué)習(xí)算法的使用中會(huì)經(jīng)常使用這兩種操作。
1、合并操作
import numpy as np
x = np.array([1, 2, 3])
y = np.array([3, 2, 1])
z = np.array([666, 666, 666]) - np.concatenate([,], axis=) 默認(rèn)axis=0,拼接之后返回的是一個(gè)新的數(shù)組。不改變?cè)袛?shù)組。
np.concatenate([x, y]) 運(yùn)行輸出結(jié)果:array([1, 2, 3, 3, 2, 1])
np.concatenate([x, y, z]) 運(yùn)行輸出結(jié)果:array([ 1, 2, 3, 3, 2, 1, 666, 666, 666])
? 上面是對(duì)一維數(shù)組的拼接,接下來看看二維的。
A = np.array([[1, 2, 3],[4, 5, 6]]) # A.shape=(2,3),從第一個(gè)維度上拼接就是(4,3)
np.concatenate([A, A]) 運(yùn)行輸出結(jié)果:
array([[1, 2, 3],[4, 5, 6],[1, 2, 3],[4, 5, 6]]) np.concatenate([A, A], axis=1) # 從第二個(gè)維度上拼接就是(2,6) 運(yùn)行輸出結(jié)果:
array([[1, 2, 3, 1, 2, 3],[4, 5, 6, 4, 5, 6]]) ? 那么,能不能把A和z拼接到一起呢?顯然是不能的,因?yàn)閦是1維數(shù)組,而A是2維數(shù)組,運(yùn)行會(huì)報(bào)錯(cuò)。z.shape=(3,),此時(shí)我們就可以使用reshape操作將其先裝換為2維數(shù)組,然后再進(jìn)行拼接。
np.concatenate([A, z.reshape(1, -1)]) 運(yùn)行輸出結(jié)果:
array([[ 1, 2, 3],[ 4, 5, 6],[666, 666, 666]])
? 其實(shí),在numpy中已經(jīng)封裝好了一個(gè)函數(shù)用來解決不同維度之間的合并問題。
- np.vstack()
np.vstack([A, z])
運(yùn)行輸出結(jié)果:
array([[ 1, 2, 3],[ 4, 5, 6],[666, 666, 666]])
- np.hstack()
B = np.full((2, 2), 100)
np.hstack([A, B])
array([[ 1, 2, 3, 100, 100],[ 4, 5, 6, 100, 100]])
2、分割操作
np.split(x, [,], axis=)
第一個(gè)參數(shù)是分割對(duì)象,第二個(gè)參數(shù)是分割點(diǎn),且分割點(diǎn)可以不唯一。axis默認(rèn)是0
x = np.arange(10)
x
運(yùn)行輸出結(jié)果:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.split(x, [3, 7])
運(yùn)行輸出結(jié)果:[array([0, 1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])]
? 同樣的,接下來試一下二維數(shù)組。
A = np.arange(16).reshape(4, 4)
A
運(yùn)行輸出結(jié)果:
array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15]])
np.split(A, [3])
運(yùn)行輸出結(jié)果:
[array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]]), array([[12, 13, 14, 15]])]
np.split(A, [3], axis=1)
運(yùn)行輸出結(jié)果:
[array([[ 0, 1, 2],[ 4, 5, 6],[ 8, 9, 10],[12, 13, 14]]), array([[ 3],[ 7],[11],[15]])]
? 其實(shí),在numpy中既然有垂直水平拼接,那就有垂直水平分割。
- np.vsplit()
np.vsplit(A, [3])
運(yùn)行輸出結(jié)果:
[array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]]), array([[12, 13, 14, 15]])]
np.hsplit(A, [3])
運(yùn)行輸出結(jié)果:
[array([[ 0, 1, 2],[ 4, 5, 6],[ 8, 9, 10],[12, 13, 14]]), array([[ 3],[ 7],[11],[15]])]
? 通過以上對(duì)比可以發(fā)現(xiàn):其實(shí)vsplit就是split的axis=0的時(shí)候,而hsplit就是split的axis=1的時(shí)候!
? 那么接下來做一個(gè)簡(jiǎn)答的小練習(xí),現(xiàn)在有下面一組數(shù)據(jù),前三列為數(shù)據(jù),最后一列為樣本標(biāo)簽,此時(shí)我們需要將其分割開來,同時(shí)把標(biāo)簽(最后一列)轉(zhuǎn)換為向量:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
data = np.arange(16).reshape(4, 4)
x, y = np.hsplit(data, [-1])
運(yùn)行輸出結(jié)果:
array([[ 0, 1, 2],[ 4, 5, 6],[ 8, 9, 10],[12, 13, 14]])
array([[ 3],[ 7],[11],[15]])
? 接下來需要把a(bǔ)rray轉(zhuǎn)換為向量。
y[:, 0]
運(yùn)行輸出結(jié)果:array([ 3, 7, 11, 15])
二、Numpy中的矩陣運(yùn)算
? 現(xiàn)在有這么一個(gè)問題:給定一個(gè)向量,讓向量中的每一個(gè)元素乘以2,a=(0,1,2),a*2=(0,2,4)
L = [i for i in range(10)]
L * 2
運(yùn)行輸出結(jié)果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
? 顯然這不是我們想要的結(jié)果。那么想要實(shí)現(xiàn)怎么辦呢?
A = []
for i in L:A.append(i * 2)
A
運(yùn)行輸出結(jié)果:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
? 這肯定不是最優(yōu)的辦法,下面就來對(duì)比幾種實(shí)現(xiàn)方式的快慢。
%%time
L = [i for i in range(100000)]
A = []
for i in L:A.append(i * 2)
A
運(yùn)行輸出結(jié)果:Wall time: 14.6 ms
%%time
L = [i*2 for i in range(100000)]
運(yùn)行輸出結(jié)果:Wall time: 6.83 ms
%%time
import numpy as np
A = np.array(i*2 for i in range(100000000000000))
A
%%time
L = np.arange(10)
L * 2
L
運(yùn)行輸出結(jié)果:Wall time: 0 ns
? 為什么是0呢?其實(shí)因?yàn)锳返回的是一個(gè)生成器,無論后面有多大的的數(shù)都是一樣的。這就是numpy在大數(shù)據(jù)運(yùn)算中的優(yōu)勢(shì)所在。關(guān)于生成器。
import numpy as np
L = np.arange(10)
L * 2
運(yùn)行輸出結(jié)果:array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])
1、Universal Function
X = np.arange(1, 16).reshape(3, 5)
X
運(yùn)行輸出結(jié)果:
array([[ 1, 2, 3, 4, 5],[ 6, 7, 8, 9, 10],[11, 12, 13, 14, 15]])
- 加法
X + 1
運(yùn)行輸出結(jié)果:
array([[ 2, 3, 4, 5, 6],[ 7, 8, 9, 10, 11],[12, 13, 14, 15, 16]])
- 減法
array([[ 0, 1, 2, 3, 4],[ 5, 6, 7, 8, 9],[10, 11, 12, 13, 14]])
- 乘法
X * 2
運(yùn)行輸出結(jié)果:
array([[ 2, 4, 6, 8, 10],[12, 14, 16, 18, 20],[22, 24, 26, 28, 30]])
- 除法
X / 2
運(yùn)行輸出結(jié)果:
array([[0.5, 1. , 1.5, 2. , 2.5],[3. , 3.5, 4. , 4.5, 5. ],[5.5, 6. , 6.5, 7. , 7.5]])
X // 2
運(yùn)行輸出結(jié)果:
array([[0, 1, 1, 2, 2],[3, 3, 4, 4, 5],[5, 6, 6, 7, 7]], dtype=int32)
- 取余
X % 2
運(yùn)行輸出結(jié)果:
array([[1, 0, 1, 0, 1],[0, 1, 0, 1, 0],[1, 0, 1, 0, 1]], dtype=int32)
- 倒數(shù)——1/X
- 絕對(duì)值——np.abs()
- 正弦函數(shù)——np.sin()
- 余弦函數(shù)——np.cos()
- 正切函數(shù)——np.tan()
- 同樣還有反正弦、反余弦、反正切等等。
- 指數(shù)函數(shù)——np.exp()
- np.power()
- np.log()
- np.log2()
- np.log10()
2、矩陣運(yùn)算
A = np.arange(4).reshape(2, 2)
B = np.full((2, 2), 10)
A+B
A-B
A*B
A/B
? 以上方法都是對(duì)應(yīng)元素進(jìn)行相應(yīng)操作,那么如果需要進(jìn)行矩陣乘法怎么辦?
矩陣乘法——np.dot()
A.dot(B)
運(yùn)行輸出結(jié)果:
array([[10, 10],[50, 50]])
- 矩陣轉(zhuǎn)置
A.T
運(yùn)行輸出結(jié)果:
array([[0, 2],[1, 3]])
- 矩陣的逆——np.linalg.inv()
np.linalg.inv(A)
運(yùn)行輸出結(jié)果:
array([[-1.5, 0.5],[ 1. , 0. ]])
np.linalg.inv(A).dot(A)
運(yùn)行輸出結(jié)果:
array([[1., 0.],[0., 1.]])
? 這也驗(yàn)證了A*A[^-1]=E
矩陣的偽逆——np.linalg.pinv()
很多情況下,我們的矩陣可能不是一個(gè)方陣,那么此時(shí)正常情況下我們是無法求得矩陣的逆的。但是可以求得偽逆矩陣。
C = np.arange(0, 16).reshape(2, 8)
C = np.arange(0, 16).reshape(2, 8)
運(yùn)行輸出結(jié)果:
array([[-1.35416667e-01, 5.20833333e-02],[-1.01190476e-01, 4.16666667e-02],[-6.69642857e-02, 3.12500000e-02],[-3.27380952e-02, 2.08333333e-02],[ 1.48809524e-03, 1.04166667e-02],[ 3.57142857e-02, -1.04083409e-17],[ 6.99404762e-02, -1.04166667e-02],[ 1.04166667e-01, -2.08333333e-02]])
C.dot(np.linalg.pinv(C))
運(yùn)行輸出結(jié)果:
array([[ 1.00000000e+00, -2.49800181e-16],[ 0.00000000e+00, 1.00000000e+00]])
? 通過上述結(jié)果可以發(fā)現(xiàn),近似單位矩陣說明求得是偽逆矩陣,近似得到的。具體偽逆矩陣的詳細(xì)求解自行百度!
3、向量和矩陣運(yùn)算
A = np.arange(4).reshape(2, 2)
v = np.array([1, 2])
- v+A
v + A
運(yùn)行輸出結(jié)果:
array([[1, 3],[3, 5]])
np.vstack([v] * A.shape[0])
運(yùn)行輸出結(jié)果:
array([[1, 2],[1, 2]])
np.vstack([v] * A.shape[0]) + A
運(yùn)行輸出結(jié)果:
array([[1, 3],[3, 5]])
? 此時(shí),可以發(fā)現(xiàn)兩者得到的結(jié)果是相同的。其實(shí)在pyhon中已經(jīng)封裝了堆疊的函數(shù)
- np.tile()
np.tile(v, (2, 1))
運(yùn)行輸出結(jié)果:
array([[1, 2],[1, 2]])
np.tile(v, (2, 1)) + A
運(yùn)行輸出結(jié)果:
array([[1, 3],[3, 5]])
- v *A
v * A
運(yùn)行輸出結(jié)果:
array([[0, 2],[2, 6]])
- A.dot(v)
A.dot(v)
運(yùn)行輸出結(jié)果:array([2, 8])
- v.dot(A)
v.dot(A)
運(yùn)行輸出結(jié)果:array([4, 7])
三、Numpy中的聚合操作
import numpy as np
L = np.random.random(100)
運(yùn)行輸出結(jié)果:
array([0.21395159, 0.90268106, 0.88705369, 0.11517909, 0.62676208,0.56121013, 0.62103571, 0.2418181 , 0.13781453, 0.66670862,0.51939238, 0.99679432, 0.06384017, 0.5974129 , 0.22196488,0.93826983, 0.83706847, 0.63491905, 0.48828241, 0.85424059,0.86514318, 0.47937265, 0.34254143, 0.89577197, 0.14823176,0.94488872, 0.57030248, 0.57643624, 0.08268558, 0.8237711 ,0.21887705, 0.46440547, 0.9338367 , 0.132422 , 0.4867988 ,0.6545799 , 0.36226663, 0.01641314, 0.67876507, 0.35811434,0.36533195, 0.12174504, 0.37477359, 0.98791281, 0.20553232,0.65235494, 0.13567244, 0.92317556, 0.82237976, 0.62747037,0.41160535, 0.46839494, 0.06753446, 0.22386476, 0.20821765,0.11778734, 0.8643039 , 0.77497708, 0.9884161 , 0.65142779,0.2374325 , 0.32467954, 0.81959546, 0.9863651 , 0.54072234,0.21293241, 0.92733881, 0.98738362, 0.90565471, 0.23441948,0.05477787, 0.69157053, 0.49194796, 0.12415383, 0.55427813,0.29040539, 0.20166942, 0.30054924, 0.30772375, 0.90932004,0.84668024, 0.51970052, 0.67773186, 0.37401172, 0.43911304,0.98495573, 0.42493635, 0.83658015, 0.35920119, 0.91977698,0.95094167, 0.03354397, 0.92045222, 0.80083071, 0.03480189,0.22378161, 0.21437509, 0.33268728, 0.51601075, 0.61235958])
- 求和——np.sum()
sum(L)
運(yùn)行輸出結(jié)果:52.28029464862967
np.sum(L)
運(yùn)行輸出結(jié)果:52.28029464862967
? 那么這兩者有什么不一樣呢?其實(shí)就是單純的效率上不一樣。
- 最小值——np.min()
np.min(L)
運(yùn)行輸出結(jié)果:0.016413139615859218
- 最大值——np.max()
np.max(L)
運(yùn)行輸出結(jié)果:0.9967943174823842
? 接下來,試一下二維數(shù)組。
X = np.arange(16).reshape(4, -1)
X
運(yùn)行輸出結(jié)果:
array([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15]])
np.sum(X)
運(yùn)行輸出結(jié)果:120
? 但是,很多時(shí)候我們并不是需要將所有的數(shù)進(jìn)行求和,而是只需要求每一行或者每一列的和。
np.sum(X, axis=0)
運(yùn)行輸出結(jié)果:array([24, 28, 32, 36])
np.sum(X, axis=1)
運(yùn)行輸出結(jié)果:array([ 6, 22, 38, 54])
? 在這里,放一個(gè)小技巧,axis=0其實(shí)就是要把行壓縮掉,那就是說不管有多少行直接壓縮為一行,那也就是將每一行放在一起求和,axis=1其實(shí)就是把列壓縮掉,最終的結(jié)果就是每一行出一個(gè)數(shù)。因?yàn)榘葱星蠛秃桶戳星蠛陀浧饋砥鋵?shí)并不是那么方便。
- 累乘——np.prod()
np.prod(X)
運(yùn)行輸出結(jié)果:0
np.prod(X + 1)
運(yùn)行輸出結(jié)果:2004189184
- 均值——np.mean()
np.mean(X)
運(yùn)行輸出結(jié)果:7.5
- 中位數(shù)——np.median()
np.median(X)
運(yùn)行輸出結(jié)果:7.5
- 百分位——np.precentile()
X = np.arange(16).reshape(4, -1)
for percent in [0, 25, 50, 75, 100]:print(np.percentile(X, q=percent))
運(yùn)行輸出結(jié)果:
0.0
3.75
7.5
11.25
15.0
- 方差——np.var()
np.var(X)
運(yùn)行輸出結(jié)果:21.25
- 標(biāo)準(zhǔn)差——np.std()
np.std(X)
運(yùn)行輸出結(jié)果:4.6097722286464435
四、Numpy中的arg運(yùn)算
1、索引操作
- np.argmin() # 最小值所在位置的索引
- np.argmax() # 最大值所在位置的索引
2、排序和索引使用
# 首先生成一個(gè)亂序數(shù)組
import numpy as np
x = np.arange(16)
np.random.shuffle(x)
x
運(yùn)行輸出結(jié)果:array([ 4, 2, 8, 14, 0, 15, 6, 3, 11, 7, 13, 1, 12, 10, 9, 5])
- np.sort(x, axis=) 默認(rèn)axis=1
np.sort(x)
運(yùn)行輸出結(jié)果:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
? 此時(shí),并沒有改變x,x仍是一個(gè)亂序的狀態(tài),如果想要直接在x上進(jìn)行排序:
x.sort()
x
運(yùn)行輸出結(jié)果:array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
? 那么對(duì)于二維矩陣呢?
X = np.random.randint(10, size=(4, 4))
X
運(yùn)行輸出結(jié)果:
array([[5, 3, 9, 2],[3, 7, 5, 7],[0, 6, 2, 0],[8, 7, 4, 8]])
np.sort(X, axis=0)
運(yùn)行輸出結(jié)果:
array([[0, 3, 2, 0],[3, 6, 4, 2],[5, 7, 5, 7],[8, 7, 9, 8]])
- np.argsort() 按照索引位置排序
import numpy as np
x = np.arange(16)
np.random.shuffle(x)
np.argsort(x)
運(yùn)行輸出結(jié)果:
array([ 1, 15, 9, 0, 10, 8, 12, 13, 5, 4, 6, 2, 3, 14, 11, 7],dtype=int64)
np.partition()
其實(shí),在很多情況下,我們并不需要將所有數(shù)進(jìn)行從大到小排序,而是尋找一個(gè)中間值,小于中間值的在左邊,大于中間值的在右邊。
np.partition(x, 3)
運(yùn)行輸出結(jié)果: array([ 0, 1, 2, 3, 9, 8, 10, 12, 5, 11, 4, 14, 6, 7, 13, 15])
- np.argpartition()
np.argpartition(x, 3)
運(yùn)行輸出結(jié)果:
array([ 1, 15, 9, 0, 4, 5, 6, 3, 8, 2, 10, 11, 12, 13, 14, 7],dtype=int64)
五、Fancy Indexing
import numpy as np
x = np.arange(16)
? 如果我們需要從3-9每間隔2個(gè)取一個(gè)數(shù)?
x[3:9:2]
運(yùn)行輸出結(jié)果: array([3, 5, 7])
? 如果我們需要去取得數(shù)據(jù)不是等間距的呢?
idx = [3, 5, 8]
x[idx]
運(yùn)行輸出結(jié)果:array([3, 5, 8])
ind = np.array([[2, 3],[4, 5]])
x[ind]
運(yùn)行輸出結(jié)果:
array([[2, 3],[4, 5]])
X = x.reshape(4, -1)
row = np.array([0, 1, 2])
col = np.array([1, 2, 3])
X[row, col]
運(yùn)行輸出結(jié)果:array([ 1, 6, 11])
col = [True, False, True, True]
X[1:3, col]
運(yùn)行輸出結(jié)果:
array([[ 4, 6, 7],[ 8, 10, 11]])
六、Numpy.array的比較
import numpy as np
x = np.arange(16)
x > 3
運(yùn)行輸出結(jié)果:
array([False, False, False, False, True, True, True, True, True,True, True, True, True, True, True, True])
'>'
'<'
'>='
'<='
'=='
'!='
? 結(jié)合剛剛學(xué)過的聚合操作,進(jìn)行一些練習(xí)。
np.sum(x <= 3)
運(yùn)行輸出結(jié)果:4
np.sum((x >= 3) & (x <= 10))
運(yùn)行輸出結(jié)果:8
np.count_nonzero(x <= 3) # True為1,False為0
運(yùn)行輸出結(jié)果:4
- np.any()
- np.all()
- 與——&
- 或——|
- 非——~
我是尾巴
? 每篇一句毒雞湯:千萬不要自己感動(dòng)自己。大部分人看似的努力,不過是愚蠢導(dǎo)致的。
我干了,你隨意!
本次推薦:一款圖片閱讀器,預(yù)覽更輕松
honeyview
堅(jiān)持!
轉(zhuǎn)載于:https://www.cnblogs.com/zhangkanghui/p/11280845.html
總結(jié)
以上是生活随笔為你收集整理的Numpy学习笔记(下篇)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做试管婴儿很疼吗
- 下一篇: VScode 插件、配置记录