numpy在cs231n中的應用
- 2019 年 10 月 5 日
- 筆記
numpy在cs231n中的應用
0.作者的話1.訪問數組2.broadcast機制3.np.bincount()4.np.argmax()5.聯合求解6.求取精度7.作者的話
0.作者的話
本節將之前發的numpy在cs231n中的應用做一個簡單的梳理,下面一起來看看,numpy的強大所在!
1.訪問數組
普通訪問
import numpy as np a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) print(a) # 獲取第3列所有數據 print(a[:,2])
輸出:
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]] [ 3 7 11]
整型數組訪問
整型數組訪問允許我們利用其它數組的數據構建一個新的數組,還是以上述的二維數組為例:
print(a[[0, 1, 2], [0, 1, 0]])
輸出:
[1 6 9]
怎麼得到的?
上述等價於
np.array生成一維度數組,一維數組的元素通過上述的普通法訪問得到。
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))
也就是說,上述a中為一個二維數組,實際上前後對應關係,然後按照普通訪問方式獲取即可!
除此之外,整型數組訪問可以用來選擇或者更改矩陣中每行中的一個元素!
仍然是以上述的二維數組為例:
b = np.array([0, 2, 1]) print(a[np.arange(3),b])
這個又該得到什麼結果?
[ 1 7 10]
為什麼?
np.arrange(3)
得到0,1,2個數,每次取出其中一個元素進行訪問,上述便轉換為a[0,0],a[1,2],a[2,1] 分別為1 7 9 10,也就是上述輸出的結果!
布爾型數組訪問
布爾型數組訪問可以選擇數組中任意元素。
這種訪問方式用於選取數組中滿足某些條件的元素。
還是以上述二維數組為例:
我們篩選所有大於3的數,並輸出。
bool_index = (a > 3) print(bool_index) print(a[bool_index]) print(a[a>3])
輸出:
[[False False False True] [ True True True True] [ True True True True]] [ 4 5 6 7 8 9 10 11 12] [ 4 5 6 7 8 9 10 11 12]
2.broadcast機制
numpy數組間的基礎運算是一對一,也就是a.shape==b.shape,但是當兩者不一樣的時候,就會自動觸發廣播機制,如下例子:
from numpy import array a = array([[ 0, 0, 0], [10,10,10], [20,20,20], [30,30,30]]) b = array([0,1,2]) print(a+b)
輸出:
[[ 0 1 2] [10 11 12] [20 21 22] [30 31 32]]
為什麼是這個樣子?
這裡以tile
模擬上述操作,來回到a.shape==b.shape情況!
# 對[0,1,2]行重複3次,列重複1次 b = np.tile([0,1,2],(4,1)) print(a+b)
輸出:
[[ 0 1 2] [10 11 12] [20 21 22] [30 31 32]]
到這裡,我們來給出一張圖:

是不是任何情況都可以呢?
當然不是,只有當兩個數組的trailing dimensions compatible時才會觸發廣播,否則報錯ValueError: frames are not aligned exception
。
上面表達意思是尾部維度必須兼容!
尾部維度:
將多維數組右對齊!能夠上下對應,這部分就是尾部,而對應的頭部維度,則是維度大的數組比維度小的數組多出來的維度!如下面實際例子:
axis: 0 1 2 a (3d array): 256 x 256 x 3 b (2d array): 256 x 3 a + b (2d array): 256 x 256 x 3
兼容
they are equal, or one of them is 1
兼容兩層意思,深入研究,第一:they are equal
尾部維度相等!
axis: 0 1 2 a (3d array): 256 x 256 x 3 b (2d array): 256 x 3 a + b (2d array): 256 x 256 x 3
第二:one of them is 1
像下面這個尾部維度不等,但是a或者b對應的元素有1存在,那麼也滿足兼容性!
axis: 0 1 2 a (3d array): 256 x 256 x 1 b (2d array): 1 x 3 a + b (2d array): 256 x 256 x 3
也就是1可以和任意維度兼容!
廣播失敗:
axis: 0 1 2 a1 (3d array): 256 x 256 x 1 b (2d array): 220 x 3 a1 + b ValueError
失敗轉化
axis: 0 1 2 3 a2 (4d array): 256 x 256 x 1 x 1 b (2d array): 220 x 3 a2 + b (4d array): 256 x 256 x 220 x 3
我們看到在a2的第三個維度增加了一個1,擴充為4維,便可以正常廣播!
如何實現a1到a2轉化?
a2 = a1[:,:,np.newaxis,:]
即可!
3.np.bincount()
首先生成一個一維數組
x = np.array([1, 2, 3, 3, 0, 1, 4])
統計索引出現次數:索引0出現1次,1出現2次,2出現1次,3出現2次,4出現1次
因此通過bincount計算出索引出現次數如下:
np.bincount(x) # [1 2 1 2 1]
上面怎麼得到的?
對於bincount計算嗎,bin的數量比x中最大數多1,例如x最大為4,那麼bin數量為5(index從0到4),也就會bincount輸出的一維數組為5個數,bincount中的數又代表什麼?代表的是它的索引值在x中出現的次數!
還是以上述x為例子,當我們設置weights參數時候,結果又是什麼?
這裡假定:
w = np.array([0.3,0.5,0.7,0.6,0.1,-0.9,1])
那麼設置這個w權重後,結果為多少?
np.bincount(x,weights=w)
輸出:
[ 0.1 -0.6 0.5 1.3 1. ]
怎麼計算的?
先對x與w抽取出來:
x ---> [1, 2, 3, 3, 0, 1, 4] w ---> [0.3,0.5,0.7,0.6,0.1,-0.9,1]
索引 0 出現在x中index=4位置,那麼在w中訪問index=4的位置即可,w[4]=0.1 索引 1 出現在x中index=0與index=5位置,那麼在w中訪問index=0與index=5的位置即可,然後將兩這個加和,計算得:w[0]+w[5]=-0.6 其餘的按照上面的方法即可!
bincount的另外一個參數為minlength,這個參數簡單,可以這麼理解,當所給的bin數量多於實際從x中得到的bin數量後,後面沒有訪問到的設置為0即可。
還是上述x為例:
這裡我們直接設置minlength=7參數,並輸出!
[1 2 1 2 1 0 0]
與上面相比多了兩個0,這兩個怎麼會多?
上面知道,這個bin數量為5,index從0到4,那麼當minlength為7的時候,也就是總長為7,index從0到6,多了後面兩位,直接補位為0即可!
4.np.argmax()
函數原型為:numpy.argmax(a, axis=None, out=None)
.
函數表示返回沿軸axis最大值的索引。
x = [[1,3,3], [7,5,2]] print(np.argmax(x)) # 3
對於這個例子我們知道,7最大,索引位置為3(這個索引按照遞增順序)!
axis屬性
axis=0表示按列操作,也就是對比當前列,找出最大值的索引!
x = [[1,3,3], [7,5,2]] print(np.argmax(x,axis=0)) # [1 1 0]
axis=1表示按行操作,也就是對比當前行,找出最大值的索引!
x = [[1,3,3], [7,5,2]] print(np.argmax(x,axis=0)) # [1 0]
那如果碰到重複最大元素?
返回第一個最大值索引即可!
例如:
x = np.array([1, 3, 2, 3, 0, 1, 0]) print(x.argmax()) # 1
5.聯合求解
這裡來融合上述兩個函數,舉個例子:
x = np.array([1, 2, 3, 3, 0, 1, 4]) print(np.argmax(np.bincount(x)))
最終結果為1,為什麼?
首先通過np.bincount(x)得到的結果是:[1 2 1 2 1],再根據最後的遇到重複最大值項,則返回第一個最大值的index即可!2的index為1,所以返回1。
6.求取精度
取指定位置的精度
In
np.around([-0.6,1.2798,2.357,9.67,13], decimals=0)
Out
看到沒,負數進位取絕對值大的!
array([-1., 1., 2., 10., 13.])
In
np.around([1.2798,2.357,9.67,13], decimals=1)
Out
array([ 1.3, 2.4, 9.7, 13. ])
In
np.around([1.2798,2.357,9.67,13], decimals=2)
Out
array([ 1.28, 2.36, 9.67, 13. ])
從上面可以看出,decimals表示指定保留有效數的位數,當超過5就會進位(此時包含5)!
但是,如果這個參數設置為負數,又表示什麼?
In
np.around([1,2,5,6,56], decimals=-1)
Out
array([ 0, 0, 0, 10, 60])
發現沒,當超過5時候(不包含5),才會進位!-1表示看一位數進位即可,那麼如果改為-2呢,那就得看兩位!
例如:
In
np.around([1,2,5,50,56,190], decimals=-2)
Out
array([ 0, 0, 0, 0, 100, 200])
看到沒,必須看兩位,超過50才會進位,190的話,就看後面兩位,後兩位90超過50,進位,那麼為200!
計算沿指定軸第N維的離散差值
In
x = np.arange(1 , 16).reshape((3 , 5))
Out
array([[ 1, 2, 3, 4, 5], [ 6, 7, 8, 9, 10], [11, 12, 13, 14, 15]])
In
np.diff(x,axis=1) #默認axis=1
Out
array([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
In
np.diff(x,axis=0)
Out
array([[5, 5, 5, 5, 5], [5, 5, 5, 5, 5]])
取整
In
np.floor([-0.6,-1.4,-0.1,-1.8,0,1.4,1.7])
Out
array([-1., -2., -1., -2., 0., 1., 1.])
看到沒,負數取整,跟上述的around一樣,是向左!
取上限
np.ceil([1.2,1.5,1.8,2.1,2.0,-0.5,-0.6,-0.3])
取上限!找這個小數的最大整數即可!
查找
利用np.where
實現小於0的值用0填充嗎,大於0的數不變!
In
x = np.array([[1, 0], [2, -2], [-2, 1]])
Out
array([[ 1, 0], [ 2, -2], [-2, 1]])
In
np.where(x>0,x,0)
Out
array([[1, 0], [2, 0], [0, 1]])