作者:樂雨泉(yuquanle),湖南大學(xué)在讀碩士,研究方向機(jī)器學(xué)習(xí)與自然語言處理。歡迎志同道合的朋友和我在公眾號'AI 小白入門'一起交流學(xué)習(xí)。
Numpy(Numeric Python)是一個用 Python 實(shí)現(xiàn)的科學(xué)計(jì)算的擴(kuò)展程序庫。 包括: 1. 一個強(qiáng)大的N維數(shù)組對象 Array; 2. 比較成熟的(廣播)函數(shù)庫; 3. 用于整合 C/C++ 和 Fortran 代碼的工具包; 4. 實(shí)用的線性代數(shù)、傅里葉變換和隨機(jī)數(shù)生成函數(shù)。 提供了許多高級的數(shù)值編程工具,如:矩陣數(shù)據(jù)類型、矢量處理,以及精密的運(yùn)算庫。 Numpy 基本操作 import numpy as np a = np.array([[1,2],[3,4]]) print(a) # 輸出'[[1 2] # [3 4]]' print(a.ndim) # 維度,輸出: 2 # 行數(shù)和列數(shù) print(a.shape) # 輸出: (2, 2) # 元素個數(shù) print(a.size) # 輸出: 4
Numpy 的數(shù)組(Array) Numpy 數(shù)組是一個由不同數(shù)值組成的網(wǎng)格, 網(wǎng)格中的數(shù)據(jù)都是同一種數(shù)據(jù)類型并且可以通過非負(fù)整型數(shù)的元組來訪問。維度的多少被稱為數(shù)組的階,數(shù)組的大小是一個由整型數(shù)構(gòu)成的元組,可以描述數(shù)組不同維度上的大小。 # 創(chuàng)建numpy數(shù)組 import numpy as np a = np.array([1, 2, 3]) # 創(chuàng)建一維數(shù)組 print(type(a)) # 輸出 '<class 'numpy.ndarray'>' print(a[0], a[1], a[2]) # 輸出 '1 2 3' a[0] = 8 # 修改數(shù)組某元素的值 print(a[0]) # 輸出 '8'
# 其他創(chuàng)建數(shù)組的方法 b = np.zeros((2, 2)) print(b) # 輸出 '[[ 0. 0.] # [ 0. 0.]]' c = np.ones((1,2)) print(c) # 輸出 '[[ 1. 1.]'
d = np.eye(2) # 創(chuàng)建單位矩陣 print(d) # 輸出 '[[ 1. 0.] # [ 0. 1.]]' e = np.random.random((2, 2)) # 隨機(jī)值 print(e) # 輸出 '[[0.29027784 0.01445969] # [0.76571518 0.75046783]]'
數(shù)組索引 Numpy 提供了多種訪問數(shù)組的方法。 import numpy as np # 切片:和Python列表類似,numpy數(shù)組也可以使用切片語法。 # 由于數(shù)組可能是多維的,因此必須為數(shù)組的每個維指定切片。
# 創(chuàng)建一個二維數(shù)組,shape為 (3,2) a = np.array([[1, 2],[3, 4],[5, 6]]) b = a[:1,1:2] print(b) # 輸出'[[2]]'
#可以同時(shí)使用整型和切片語法來訪問數(shù)組。這樣做會產(chǎn)生比原數(shù)組低階的新數(shù)組。 row_r1 = a[1, :] row_r2 = a[1:2, :] print(row_r1, row_r1.shape) # Prints '[3 4] (2,)' print(row_r2, row_r2.shape) # Prints '[[3 4]] (1, 2)'
# 使用切片語法訪問數(shù)組時(shí),得到的總是原數(shù)組的一個子集 # 整型數(shù)組訪問允許我們利用其它數(shù)組的數(shù)據(jù)構(gòu)建一個新的數(shù)組 a1 = np.array([[1,2], [3, 4], [5, 6]])
print(a1[[0, 1, 2], [0, 1, 0]]) # Prints '[1 4 5]' # 等價(jià)于以下操作 print(np.array([a1[0, 0], a1[1, 1], a1[2, 0]]))
# 布爾型數(shù)組訪問:布爾型數(shù)組訪問可以讓你選擇數(shù)組中任意元素 # 這種訪問方式用于選取數(shù)組中滿足某些條件的元素 a2 = np.array([[1,2], [3, 4], [5, 6]]) b2 = (a > 2) print(b2) print(a2[b2]) # 輸出 '[3 4 5 6]' # 等價(jià)于 print(a[a>2]) # 輸出 '[3 4 5 6]'
數(shù)據(jù)類型 每個 Numpy 數(shù)組的元素?cái)?shù)據(jù)類型相同。創(chuàng)建數(shù)組的時(shí)候,Numpy 會嘗試猜測數(shù)組的數(shù)據(jù)類型,當(dāng)然也可以通過參數(shù)直接指定數(shù)據(jù)類型。 import numpy as np x1 = np.array([1, 2]) # numpy選擇類型 print(x1.dtype) # 輸出'int32'
x2 = np.array([1.0, 2.0]) # numpy選擇類型 print(x2.dtype) # 輸出'float64'
x3 = np.array([1, 2], dtype=np.int64) # 指定類型 print(x3.dtype) # 輸出'int64'
數(shù)組計(jì)算 基本數(shù)學(xué)計(jì)算函數(shù)會對數(shù)組中元素逐個進(jìn)行計(jì)算,既可以利用操作符重載,也可以使用函數(shù)方式。 import numpy as np
x = np.array([[1,2],[3,4]], dtype=np.float64) y = np.array([[5,6],[7,8]], dtype=np.float64)
# 按元素相加,產(chǎn)生的還是同樣shape的數(shù)組 # 輸出 '[[ 6. 8.] # [10. 12.]]' print(x + y) print(np.add(x, y))
# 按元素相減 # 輸出 '[[ 6. 8.] # [10. 12.]]' print(x - y) print(np.subtract(x, y))
# 按元素相乘 # 輸出 '[[ 5. 12.] # [21. 32.]]' print(x * y) print(np.multiply(x, y))
# 按元素相除 # 輸出 '[[0.2 0.33333333] # [0.42857143 0.5 ]]' print(x / y) print(np.divide(x, y))
# 開平方 # 輸出 '[[1. 1.41421356] # [1.73205081 2. ]]' print(np.sqrt(x))
# numpy矩陣乘法 x = np.array([[1,2],[3,4]]) y = np.array([[5,6],[7,8]])
v = np.array([9,10]) w = np.array([11, 12])
# 向量的內(nèi)積,輸出:219 print(v.dot(w)) print(np.dot(v, w))
# 向量/矩陣乘積 # 輸出 '[29 67]' print(x.dot(v)) print(np.dot(x, v))
# 矩陣/矩陣乘積 # 輸出 '[[19 22] # [43 50]]' print(x.dot(y)) print(np.dot(x, y))
# 求和函數(shù)sum x = np.array([[1,2],[3,4]]) print(np.sum(x)) # 所有元素相加,輸出'10' print(np.sum(x, axis=0)) # 按列相加,輸出'[4 6]' print(np.sum(x, axis=1)) # 按行相加,輸出'[3 7]'
# 轉(zhuǎn)置操作 x = np.array([[1,2], [3,4]]) print(x) # 輸出 '[[1 2] # [3 4]]' print(x.T) # 輸出 '[[1 3] # [2 4]]'
廣播機(jī)制(Broadcasting) 廣播是一種強(qiáng)有力的機(jī)制,可以讓不同大小的矩陣進(jìn)行數(shù)學(xué)計(jì)算。我們常常會有一個小的矩陣和一個大的矩陣,然后我們會需要用小的矩陣對大的矩陣做一些計(jì)算。 # 把一個向量加到矩陣的每一行,可以這樣做 import numpy as np x = np.array([[1,2,3], [4,5,6], [7,8,9]]) v = np.array([1, 0, 1]) y = np.empty_like(x) # 創(chuàng)建一個空矩陣,shape和x一致
for i in range(3): y[i, :] = x[i, :] + v print(y)
# 輸出 # [[ 2 2 4] # [ 5 5 7] # [ 8 8 10]]
# 當(dāng)x矩陣非常大,利用循環(huán)來計(jì)算就會變得很慢很慢 # 換一種思路 vv = np.tile(v, (3, 1)) # 將v復(fù)制三次堆疊在一起 print(vv) # 輸出 '[[1 0 1] # [1 0 1] # [1 0 1]'
y = x + vv # 按元素相加 print(y)
# Numpy廣播機(jī)制讓我們不用創(chuàng)建vv,就能直接運(yùn)算 y = x + v # 使用廣播將v添加到x的每一行 print(y)
# 廣播機(jī)制例子 # 1.計(jì)算向量的外積
v = np.array([1,2,3]) # v 的shape (3,) w = np.array([4,5]) # w 的shape (2,) # 首先將v轉(zhuǎn)化成(3, 1),然后廣播 # 輸出的shape為(3, 2) # [[ 4 5] # [ 8 10] # [12 15]] print(np.reshape(v, (3, 1)) * w)
# 2.向矩陣的每一行添加一個向量 x = np.array([[1,2,3], [4,5,6]]) # x的shape為(2,3),v的shape為(3,),因此它們廣播得到(2,3) # 輸出: # [[2 4 6] # [5 7 9]] print(x + v)
# 3.向矩陣的每一列添加一個向量 # x 的shape (2, 3) and w的shape (2,). # 轉(zhuǎn)置x的shape(3,2),針對w廣播以產(chǎn)生形狀的結(jié)果(3,2) # 輸出: # [[ 5 6 7] # [ 9 10 11]] print((x.T + w).T)
# 4.另一個解決方案是將w重塑shape為(2,1) # 然后可以直接對x廣播它以產(chǎn)生相同的效果 # 輸出 print(x + np.reshape(w,(2,1)))
# 5.用常數(shù)乘以矩陣 # 輸出: # [[ 2 4 6] # [ 8 10 12]] print(x * 2)
參考: https://github.com/kuleshov/cs228-material/blob/master/tutorials/python/cs228-python-tutorial.ipynb
|