Numpy 入門

samay發表於2018-01-02

簡介

numpy是python的一個開源的數值計算庫,該庫可以用來儲存和處理大型矩陣,比python的自帶的list和tuple處理效率更高。

numpy的建立和引入

numpy是python的一個開源庫,安裝好python後可以採用如下的方式,安裝numpy。

    pip3 install numpy
複製程式碼

程式碼中引入numpy也很簡單,採用如下方式就可以了。

    import numpy as np
複製程式碼

矩陣的建立

常規的方法:

  1. 一維矩陣
    array1=np.array([1,2,3,4,5])
複製程式碼
  1. 二維矩陣
    array1=np.array([[1,2,3,4,5],[2,3,4,5,6]])
複製程式碼
  1. 三維矩陣
    array1=np.array([[[1,2,3,4,5],[2,3,4,5,6]]])
複製程式碼

可以看出建立什麼樣可以將相關矩陣直接傳入就可以了。

快捷的方法是

  1. 建立全0矩陣,其中(2,3)表示生成的是2行,3列的矩陣
	x=np.zeros((2,3))  
	print(x)    
	#輸出內容
	#[[0,0,0]
	# [0,0,0]]
複製程式碼
  1. 建立全1矩陣,其中(2,3)表示生成的是2行,3列的矩陣
	x=np.ones((2,3)) 
	print(x)
	#輸出內容
	#[[1,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]]
複製程式碼
  1. 建立單元矩陣,其中2表示的是2*2的矩陣
	x=np.eye(2)
	print(x)
	#輸出內容
	#[[ 1.  0.]
    # [ 0.  1.]]
複製程式碼
  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]]
複製程式碼
  1. 建立指定形狀的隨機矩陣
	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就不會隨之變化。

相關文章