簡介
numpy是python的一個開源的數值計算庫,該庫可以用來儲存和處理大型矩陣,比python的自帶的list和tuple處理效率更高。
numpy的建立和引入
numpy是python的一個開源庫,安裝好python後可以採用如下的方式,安裝numpy。
pip3 install numpy
複製程式碼
程式碼中引入numpy也很簡單,採用如下方式就可以了。
import numpy as np
複製程式碼
矩陣的建立
常規的方法:
- 一維矩陣
array1=np.array([1,2,3,4,5])
複製程式碼
- 二維矩陣
array1=np.array([[1,2,3,4,5],[2,3,4,5,6]])
複製程式碼
- 三維矩陣
array1=np.array([[[1,2,3,4,5],[2,3,4,5,6]]])
複製程式碼
可以看出建立什麼樣可以將相關矩陣直接傳入就可以了。
快捷的方法是
- 建立全0矩陣,其中(2,3)表示生成的是2行,3列的矩陣
x=np.zeros((2,3))
print(x)
#輸出內容
#[[0,0,0]
# [0,0,0]]
複製程式碼
- 建立全1矩陣,其中(2,3)表示生成的是2行,3列的矩陣
x=np.ones((2,3))
print(x)
#輸出內容
#[[1,1,1]
# [1,1,1]]
複製程式碼
- 建立一個empty矩陣,需要說明該方法生成不是真正意義上的empty矩陣,而是不限接近於0的矩陣,其中(2,3)表示生成的是2行,3列的矩陣
empty=np.empty((2,3))
print(empty)
#輸出內容
#[[0.00000000e+000 2.31584192e+077 1.48219694e-323]
# [nan 2.13839732e-314 4.17203541e-309]]
複製程式碼
4,建立一個full矩陣,其中(2,2)表示生成的為2行,2列的矩陣,7為矩陣資料都是為7.
x=np.full((2,2),7)
print(x)
#輸出內容
#[[7 7]
#[7 7]]
複製程式碼
- 建立單元矩陣,其中2表示的是2*2的矩陣
x=np.eye(2)
print(x)
#輸出內容
#[[ 1. 0.]
# [ 0. 1.]]
複製程式碼
- 建立指定最大最小值和步長,形狀的矩陣
x=np.arange(10).reshape(2,5) #從0,9的2行5列的矩陣
print(x)
#輸出內容
#[[0 1 2 3 4]
# [5 6 7 8 9]]
x=np.arange(4,12).reshape(2,4) #從4,11的2行5列的矩陣
print(x)
#輸出內容
#[[ 4 5 6 7]
# [ 8 9 10 11]]
x=np.arange(1,20,3).reshape(1,7) #從1,20 步長為3的的1行7列的矩陣
print(x)
#輸出內容
#[[ 1 4 7 10 13 16 19]]
複製程式碼
- 建立指定形狀的隨機矩陣
x=np.random.random((3,2)) #生成3行2列,0到1之間隨機數的矩陣
print(x)
#輸出內容:
#[[ 0.02877225 0.0536815 ]
# [ 0.95767806 0.63741724]
# [ 0.10975063 0.78859285]]
x=np.random.randint(0,10,(3,2)) #生成3行2列,0到10之間隨機整數的矩陣
print(x)
#輸出內容:
#[[7 9]
# [1 8]
# [6 3]]
x=np.random.normal(size=(3,2)) #生成3行2列,符合正態分佈的矩陣
print(x)
#輸出內容:
#[[ 1.24485604 -0.73626677]
# [ 1.3671711 -0.24442532]
# [-1.08691618 -0.6656498 ]]
複製程式碼
矩陣的訪問
切片訪問:numpy矩陣可以使用類似python切片的方式,訪問矩陣內容。但是矩陣是多維的,因此指定每個維度指定好切片。
x=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16])
y=x[:3,1:3]
print(y)
#輸出內容(輸出0,1,2行,1,2列(行列都是以0開頭))
#[[ 2 3]
# [ 6 7]
# [10 11]]
print(x[2,3])
#輸出內容(輸出1行,第2列的數值(行列都是以0開頭))
#12
y[0, 0] = 77
print(x[0, 1])
#輸出內容
#77
#發現修改了y的值,導致了x值發生了改變。原因是y[0, 0]和x[0, 1]是同一個值,兩者有一個改變,另一個值會跟著發生改變。
複製程式碼
整型陣列訪問:採用整型陣列訪問矩陣
x=np.array([[1,2], [3, 4], [5, 6]])
print(x[[0,1,2],[0,1,0]])
#輸出內容
#[1 4 5]
print(np.array([x[0,0],x[1,1],x[2,0]]))
#輸出內容
#[1 4 5]
複製程式碼
可以看出這個方式獲得值是一樣的。第二種方法比較簡單,是典型的切片訪問的方式。第一種方式是傳入了兩個陣列[0,1,2]和[0,1,0],numpy在方式訪問矩陣時將兩個陣列解析為(0,0),(1,1),(2,0)這三個組合訪問矩陣。按照此思路,如下code輸出如下。
x=np.array([[1,2], [3, 4], [5, 6]])
print(x[[0, 1], [1, 0]])
#輸出內容:
#[2 3]
print(np.array([x[0,1],x[1,0]]))
#輸出內容:
#[2 3]
複製程式碼
布林型陣列訪問:布林型陣列可以訪問矩陣中滿足某些條件的元素
x=np.array([[1,2], [3, 4], [5, 6]])
bool_idx=(x>2)
print(bool_idx)
#輸出內容:
#[[False False]
# [True True]
# [True True]]
print(x[bool_idx])
#輸出內容:
#[3 4 5 6]
print(x[x>2])
#輸出內容:
#[3 4 5 6]
複製程式碼
矩陣的計算
基礎運算
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6], [7, 8]])
print(np.add(x,y)) #np.add(x,y)和(x+y)等價
#輸出內容:
#[[ 6 8]
# [10 12]]
print(np.subtract(x,y)) #np.subtract(x,y)和(x-y)等價
#輸出內容:
#[[-4 -4]
# [-4 -4]]
print(np.multiply(x,y)) #np.multiply(x,y)和(x*y)等價
#輸出內容:
#[[ 5 12]
# [21 32]]
print(np.divide(x,y)) #np.divide(x,y)和(x/y)等價
#輸出內容:
#[[ 0.2 0.33333333]
# [ 0.42857143 0.5 ]]
print(np.sqrt(x)) #矩陣中每個元素的開方
#輸出內容:
#[[ 1. 1.41421356]
# [ 1.73205081 2. ]]
print(np.sum(x)) #矩陣x所有資料累加 等價於x.sum()
#輸出內容:
#10
print(np.sum(x,axis=0)) #矩陣x列相累加 等價於x.sum(axis=0)
#輸出內容:
#[4 6]
print(np.sum(x,axis=1)) #矩陣y行累加 等價於等價於x.sum(axis=1)
#輸出內容:
#[3 7]
複製程式碼
note:類似還有求平均值(np.mean(x)或x.mean()),求最小值索引(np.argmin(x)或x.argmin(x))等方法
矩陣乘法。如上述程式碼我們可以看到採用multiply或*相乘,是將每個元素相乘並不是矩陣乘法。因此採用如下方法進行矩陣乘法
a = np.array([[1, 2], [3, 4]])
b = np.array([11, 12])
print(a.dot(b)) # 等價於np.dot(a,b)
#輸出內容:
#[35 81]
複製程式碼
矩陣轉置。矩陣的轉置是比較線性代數中比較常見一個計算方式
a = np.array([[1, 2], [3, 4]])
print(a)
#輸出內容:
#[[1 2]
# [3 4]]
print(a.T) #等價於np.transpose(a)
#輸出內容:
#[[1 3]
# [2 4]]
複製程式碼
note:需要指出如果矩陣是[1,2,3]這種一維矩陣,轉置矩陣和原矩陣輸出是一致的。
矩陣的引數
使用numpy可以獲得建立矩陣的相關引數,主要獲得引數的方法如下。 ndim 矩陣的維度
x=np.array([1,2,3,4,5])
y=np.array([[1,2,3],[4,5,6]])
print('x number of dim:',x.ndim)
#輸出內容:
#x number of dim:1
print('y number of dim:',y.ndim)
#輸出內容:
#y number of dim:2
複製程式碼
shape 矩陣的形狀
x=np.array([1,2,3,4,5])
y=np.array([[1,2,3],[4,5,6]])
print('x shape:',x.shape)
#輸出內容:x shape : (5,)
print('y shape:',y.shape)
#輸出內容:y shape : (2, 3)
複製程式碼
size 矩陣的大小
x=np.array([1,2,3,4,5])
y=np.array([[1,2,3],[4,5,6]])
print('x size :',x.size)
#輸出內容:x size : 5
print('y size :',y.size)
#輸出內容:y size : 6
複製程式碼
dtype 元素型別
x=np.array([1,2,3,4,5])
y=np.array([[1,2,3],[4,5,6]])
print('x dtype :',x.dtype)
#輸出內容:x dtype : int64
print('y dtype :',y.dtype)
#輸出內容:y dtype : int64
複製程式碼
矩陣的合併
在numpy中矩陣的合併主要採用如下的方法
a=np.array([[1,2],[3,4]])
b=np.array([[5,6],[7,8]])
c=np.hstack((a,b)) #矩陣的橫向合併
print(c)
#輸出內容
#[[1 2 5 6]
# [3 4 7 8]]
d=np.vstack((a,b)) #矩陣的縱向合併
print(d)
#輸出內容
#[[1 2]
# [3 4]
# [5 6]
# [7 8]]
e=np.concatenate((a,b),axis=0) #矩陣的橫向合併
print(e)
#輸出內容
#[[1 2]
# [3 4]
# [5 6]
# [7 8]]
f=np.concatenate((a,b),axis=1) #矩陣的縱向合併
print(f)
#輸出內容
#[[1 2 5 6]
# [3 4 7 8]]
複製程式碼
note:矩陣的合併有比較大的條件限制,矩陣合併首先要保證合併矩陣的維度必須是一致的,而且形狀也需要符合合併的要求。
矩陣的切分
numpy對於矩陣的切分主要有如下幾個方式。
a = np.arange(0, 12).reshape((3, 4))
print(a)
#輸出內容為:
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
b=np.hsplit(a,2) #行切分矩陣
#輸出內容為:
#[array([[0, 1],
# [4, 5],
# [8, 9]]),
# array([[ 2, 3],
# [ 6, 7],
# [10, 11]])]
print(b)
c=np.vsplit(a,1) #列切分矩陣
print(c)
#輸出內容:
#[array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])]
d=np.split(a,2,axis=1) #axis=1 表示行切分矩陣,axis=0 表示列切分矩陣,平均切分。如果不能平局切分會報錯
print(d)
#輸出內容:
#[array([[0, 1],
# [4, 5],
# [8, 9]]),
# array([[ 2, 3],
# [ 6, 7],
# [10, 11]])]
d=np.array_split(a,3,axis=1) #axis=1 表示行切分矩陣,axis=0 表示列切分矩陣。與split不同的是可以平均切分
print(d)
#輸出內容:
#[array([[0, 1],
# [4, 5],
# [8, 9]]),
# array([[ 2],
# [ 6],
# [10]]),
# array([[ 3],
# [ 7],
# [11]])]
複製程式碼
矩陣的深拷貝和淺拷貝
在使用numpy我們常常會遇到如下的場景
a=np.arange(0,8).reshape(4,2)
print(a)
#輸出內容:
#[[0 1]
# [2 3]
# [4 5]
# [6 7]]
b=a[2,:]
b[0]=11
print(a)
#輸出內容:
#[[0 1]
# [2 3]
# [11 5]
# [6 7]]
複製程式碼
發現我們修改了b的值,但是a隨之改變。這裡我們可以這裡資料關聯看作C中指標,改變一個資料本質上另一個資料也隨之發生改變。 如果解決這個問題,可以採用深拷貝的知識,具體實現如下
a=np.arange(0,8).reshape(4,2)
print(a)
#輸出內容:
#[[0 1]
# [2 3]
# [4 5]
# [6 7]]
b=np.copy(a)[2,:]
b[0]=11
print(a)
#輸出內容:
#[[0 1]
# [2 3]
# [4 5]
# [6 7]]
複製程式碼
採用np.copy方法對a進行深拷貝,那麼修改b的值,a就不會隨之變化。