作者:樂(lè)雨泉(yuquanle),湖南大學(xué)在讀碩士,研究方向機(jī)器學(xué)習(xí)與自然語(yǔ)言處理。歡迎志同道合的朋友和我在公眾號(hào)'AI 小白入門(mén)'一起交流學(xué)習(xí)。
Numpy(Numeric Python)是一個(gè)用 Python 實(shí)現(xiàn)的科學(xué)計(jì)算的擴(kuò)展程序庫(kù)。
包括:
1. 一個(gè)強(qiáng)大的N維數(shù)組對(duì)象 Array;
2. 比較成熟的(廣播)函數(shù)庫(kù);
3. 用于整合 C/C++ 和 Fortran 代碼的工具包;
4. 實(shí)用的線性代數(shù)、傅里葉變換和隨機(jī)數(shù)生成函數(shù)。
提供了許多高級(jí)的數(shù)值編程工具,如:矩陣數(shù)據(jù)類(lèi)型、矢量處理,以及精密的運(yùn)算庫(kù)。
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)
# 元素個(gè)數(shù)
print(a.size) # 輸出: 4
Numpy 的數(shù)組(Array)
Numpy 數(shù)組是一個(gè)由不同數(shù)值組成的網(wǎng)格, 網(wǎng)格中的數(shù)據(jù)都是同一種數(shù)據(jù)類(lèi)型并且可以通過(guò)非負(fù)整型數(shù)的元組來(lái)訪問(wèn)。維度的多少被稱為數(shù)組的階,數(shù)組的大小是一個(gè)由整型數(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 提供了多種訪問(wèn)數(shù)組的方法。
import numpy as np
# 切片:和Python列表類(lèi)似,numpy數(shù)組也可以使用切片語(yǔ)法。
# 由于數(shù)組可能是多維的,因此必須為數(shù)組的每個(gè)維指定切片。
# 創(chuàng)建一個(gè)二維數(shù)組,shape為 (3,2)
a = np.array([[1, 2],[3, 4],[5, 6]])
b = a[:1,1:2]
print(b) # 輸出'[[2]]'
#可以同時(shí)使用整型和切片語(yǔ)法來(lái)訪問(wèn)數(shù)組。這樣做會(huì)產(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)'
# 使用切片語(yǔ)法訪問(wèn)數(shù)組時(shí),得到的總是原數(shù)組的一個(gè)子集
# 整型數(shù)組訪問(wèn)允許我們利用其它數(shù)組的數(shù)據(jù)構(gòu)建一個(gè)新的數(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ù)組訪問(wèn):布爾型數(shù)組訪問(wèn)可以讓你選擇數(shù)組中任意元素
# 這種訪問(wèn)方式用于選取數(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ù)類(lèi)型
每個(gè) Numpy 數(shù)組的元素?cái)?shù)據(jù)類(lèi)型相同。創(chuàng)建數(shù)組的時(shí)候,Numpy 會(huì)嘗試猜測(cè)數(shù)組的數(shù)據(jù)類(lèi)型,當(dāng)然也可以通過(guò)參數(shù)直接指定數(shù)據(jù)類(lèi)型。
import numpy as np
x1 = np.array([1, 2]) # numpy選擇類(lèi)型
print(x1.dtype) # 輸出'int32'
x2 = np.array([1.0, 2.0]) # numpy選擇類(lèi)型
print(x2.dtype) # 輸出'float64'
x3 = np.array([1, 2], dtype=np.int64) # 指定類(lèi)型
print(x3.dtype) # 輸出'int64'
數(shù)組計(jì)算
基本數(shù)學(xué)計(jì)算函數(shù)會(huì)對(duì)數(shù)組中元素逐個(gè)進(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))
# 開(kāi)平方
# 輸出 '[[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ì)算。我們常常會(huì)有一個(gè)小的矩陣和一個(gè)大的矩陣,然后我們會(huì)需要用小的矩陣對(duì)大的矩陣做一些計(jì)算。
# 把一個(gè)向量加到矩陣的每一行,可以這樣做
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)建一個(gè)空矩陣,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)來(lái)計(jì)算就會(huì)變得很慢很慢
# 換一種思路
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.向矩陣的每一行添加一個(gè)向量
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.向矩陣的每一列添加一個(gè)向量
# x 的shape (2, 3) and w的shape (2,).
# 轉(zhuǎn)置x的shape(3,2),針對(duì)w廣播以產(chǎn)生形狀的結(jié)果(3,2)
# 輸出:
# [[ 5 6 7]
# [ 9 10 11]]
print((x.T + w).T)
# 4.另一個(gè)解決方案是將w重塑shape為(2,1)
# 然后可以直接對(duì)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
作者簡(jiǎn)介
聯(lián)系客服