1. 程式人生 > >Python中的numpy庫介紹!

Python中的numpy庫介紹!

機器學習演算法中大部分都是呼叫Numpy庫來完成基礎數值計算的。
安裝方法:

pip3 install numpy

1. ndarray陣列基礎
python中用列表儲存一組值,可將列表當陣列使用。另外,python中有array模組,但它不支援多維陣列,無論是時列表還是array模組都沒有科學運算函式,不適合做矩陣等科學計算。numpy沒有使用python本身的陣列機制,而是提供了ndarray物件,該物件不僅能方便地存取陣列,而且擁有豐富的陣列計算函式。
使用前先匯入Numpy模組

import numpy as np
#或
from numpy import *

1)陣列的建立及使用

>>> x=np.array([[1.0,0.0,0.0],[0.,1.,2.]]) #定義了一個二維陣列,大小為(2,3)
>>> x
array([[1., 0., 0.],
       [0., 1., 2.]])
>>> x.ndim   #陣列維度數
2
>>> x.shape    #陣列的維數,返回的格式(n,m),其中n為行數,m為列數
(2, 3)
>>> x.size    #陣列元素的總數
6
>>> x.dtype   #陣列元素型別
dtype('float64')  #64位浮點型
>>> x.itemsize  #每個元素佔有的位元組大小
8
>>> x.data    #陣列元素的緩衝區
<memory at 0x00000205227DAC18>

另外,還有兩種建立序列陣列的函式arrange和linspace,和range函式類似,但它們都屬於Numpy裡面。
arange(a,b,c) 引數分別表示開始值,結束值,步長
linspace(a,b,c) 引數分別表示開始值,結束值,元素數量
還可以呼叫它們自身的方法reshape()指定形狀

>>> arange(15).reshape(3,5)
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> arange(10,30,5)
array([10, 15, 20, 25])
>>> arange(0,2,0.3)
array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])
>>> linspace(0,2,9)
array([0.  , 0.25, 0.5 , 0.75, 1.  , 1.25, 1.5 , 1.75, 2.  ])

2)特殊陣列

  • zeros陣列:全零陣列,元素全為零。
  • ones陣列:全1陣列,元素全為1。
  • empty陣列:空陣列,元素全近似為0。
>>> zeros((3,4))
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> ones((2,3,4),dtype=int16)
array([[[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]],

       [[1, 1, 1, 1],
        [1, 1, 1, 1],
        [1, 1, 1, 1]]], dtype=int16)
>>> empty((5,3))
array([[6.23042070e-307, 1.42417221e-306, 1.37961641e-306],
       [1.11261027e-306, 1.11261502e-306, 1.42410839e-306],
       [7.56597770e-307, 6.23059726e-307, 1.42419530e-306],
       [7.56599128e-307, 1.11260144e-306, 6.89812281e-307],
       [2.22522596e-306, 2.22522596e-306, 2.56761491e-312]])

3)陣列索引
Numpy陣列每個元素,每行元素,每列元素都可以用索引訪問。

>>> c=arange(24).reshape(2,3,4)
>>> print(c)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
>>> print(c[1,2,:])
[20 21 22 23]
>>> print(c[0,1,2])
6

4)陣列運算
陣列的加減乘除以及乘方運算方式為,相應位置的元素分別進行運算。

>>> a=array([20,30,40,50])
>>> aa=arange(1,5)
>>> a/aa
array([20.        , 15.        , 13.33333333, 12.5       ])
>>> b=arange(4)
>>> b
array([0, 1, 2, 3])
>>> c=a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9], dtype=int32)
>>> A=array([[1,1],[0,1]])
>>> b=array([[2,0],[3,4]])
>>> A*b
array([[2, 0],
       [0, 4]])
>>> A.sum()
3
>>> A.min()
0
>>> A.max()
1

5)陣列的拷貝
陣列的拷貝分淺拷貝和深拷貝兩種,淺拷貝通過陣列變數的賦值完成,深拷貝使用陣列物件的copy方法。
淺拷貝只拷貝陣列的引用,如果對拷貝進行修改,源陣列也將修改。如下:

>>> a=ones((2,3))
>>> a
array([[1., 1., 1.],
       [1., 1., 1.]])
>>> b=a
>>> b[1,2]=2
>>> a
array([[1., 1., 1.],
       [1., 1., 2.]])
>>> b
array([[1., 1., 1.],
       [1., 1., 2.]])

深拷貝會複製一份和源陣列一樣的陣列,新陣列與源陣列會存放在不同記憶體位置,因此對新陣列的修改不會影響源陣列。如下:

>>> a=ones((2,3))
>>> b=a.copy()
>>> b[1,2]=2
>>> a
array([[1., 1., 1.],
       [1., 1., 1.]])
>>> b
array([[1., 1., 1.],
       [1., 1., 2.]])

2. 矩陣
1)建立矩陣
Numpy的矩陣物件與陣列物件相似,主要不同之處在於,矩陣物件的計算遵循矩陣數學運算規律。矩陣使用matrix函式建立。

>>> A=matrix('1.0 2.0;3.0 4.0')
>>> A
matrix([[1., 2.],
        [3., 4.]])
>>> b=matrix([[1.0,2.0],[3.0,4.0]])
>>> b
matrix([[1., 2.],
        [3., 4.]])
>>> type(A)
<class 'numpy.matrixlib.defmatrix.matrix'>

2)矩陣運算
矩陣的常用數學運算有轉置,乘法,求逆等。

>>> A.T      #轉置
matrix([[1., 3.],
        [2., 4.]])
>>> x=matrix('5.0 7.0')
>>> y=x.T
>>> y
matrix([[5.],
            [7.]])
>>> print(A*y)   #矩陣乘法
[[19.]
 [43.]]
>>> print(A.I)   #逆矩陣
[[-2.   1. ]
 [ 1.5 -0.5]]

Numpy線性代數相關函式

  • numpy.dot()
    此函式返回兩個陣列的點積。 對於二維向量,其等效於矩陣乘法。 對於一維陣列,它是向量的內積。 對於 N 維陣列,它是a的最後一個軸上的和與b的倒數第二個軸的乘積。
>>> a=np.array([[1,2],[3,4]])
>>> b=np.array([[11,12],[13,14]])
>>> np.dot(a,b)
array([[37, 40],     #[[1*11+2*13, 1*12+2*14],[3*11+4*13, 3*12+4*14]]
       [85, 92]])
  • numpy.vdot()
    此函式返回兩個向量的點積。 如果第一個引數是複數,那麼它的共軛複數會用於計算。 如果引數id是多維陣列,它會被展開。
>>> np.vdot(a,b)
130    #1*11+2*12+3*13+4*14=130
  • numpy.inner()
    此函式返回一維陣列的向量內積。 對於更高的維度,它返回最後一個軸上的和的乘積。
>>> x=np.array([1,2,3])
>>> y=np.array([0,1,0])
>>> print(np.inner(x,y))
2      # 等價於 1*0+2*1+3*0
  • numpy.matmul()
    函式返回兩個陣列的矩陣乘積。 雖然它返回二維陣列的正常乘積,但如果任一引數的維數大於2,則將其視為存在於最後兩個索引的矩陣的棧,並進行相應廣播。
    另一方面,如果任一引數是一維陣列,則通過在其維度上附加 1 來將其提升為矩陣,並在乘法之後被去除。
#對二維陣列(列表),就相當於矩陣乘法
>>> a=[[1,0],[0,1]]
>>> b=[[4,1],[2,2]]
>>> print(np.matmul(a,b))
[[4 1]
 [2 2]]
 #二維和一維運算
 >>> a=[[1,0],[0,1]]
>>> b=[1,2]
>>> print(np.matmul(a,b))
[1 2]
>>> print(np.matmul(b,a))
[1 2]
#維度大於2的
>>> a=np.arange(8).reshape(2,2,2)
>>> b=np.arange(4).reshape(2,2)
>>> print(np.matmul(a,b))
[[[ 2  3]
  [ 6 11]]

 [[10 19]
  [14 27]]]
  • numpy.linalg.det()
    行列式線上性代數中是非常有用的值。 它從方陣的對角元素計算。 對於 2×2 矩陣,它是左上和右下元素的乘積與其他兩個的乘積的差。
    換句話說,對於矩陣[[a,b],[c,d]],行列式計算為ad-bc。 較大的方陣被認為是 2×2 矩陣的組合。
    numpy.linalg.det()函式計算輸入矩陣的行列式。
>>> a=np.array([[1,2],[3,4]])
>>> print(np.linalg.det(a))
-2.0000000000000004
>>> b=np.array([[6,1,1],[4,-2,5],[2,8,7]])
>>> print(b)
[[ 6  1  1]
 [ 4 -2  5]
 [ 2  8  7]]
>>> print(np.linalg.det(b))
-306.0
>>> print(6*(-2*7-5*8)-1*(4*7-5*2)+(4*8- -2*2))
-306
  • numpy.linalg.solve()
    該函式給出了矩陣形式的線性方程的解。
    例:
    x + y + z = 6
    2y + 5z = -4
    2x + 5y - z = 27
    寫成矩陣形勢
    在這裡插入圖片描述
    可表示為AX=B
    即求X=A^(-1)B
    逆矩陣可以用numpy.linalg.inv()函式來求
>>> x=np.array([[1,2],[3,4]])
>>> y=np.linalg.inv(x)
>>> x
array([[1, 2],
       [3, 4]])
>>> y
array([[-2. ,  1. ],
       [ 1.5, -0.5]])
>>> np.dot(x,y)
array([[1.0000000e+00, 0.0000000e+00],
       [8.8817842e-16, 1.0000000e+00]])

計算線性方程的解

a=np.array([[1,1,1],[0,2,5],[2,5,-1]])
print('陣列a:')
print(a)
ainv=np.linalg.inv(a)
print('a的逆矩陣')
print(ainv)
print('矩陣b:')
b=np.array([[6],[-4],[27]])
print(b)
print('計算:A^(-1)B:')
x=np.linalg.solve(a,b)
print(x)

輸出如下:

在這裡插入圖片描述
完畢!