Python——numpy

Numpy介紹:

Numpy是用來存儲和處理大型矩陣,比Python自身的嵌套列表結構要高效的多,本身是由C語言開發。這個是很基礎的擴展,其餘的擴展都是以此爲基礎。

Numpy常用操作

定義矩陣變量並輸出變量的一些屬性:

# -*-coding:utf-8-*-
import numpy as np
# 用np.array()生成矩陣
arr=np.array([[1,2,3],
              [4,5,6]])

print(arr)
print('number of arr dimensions: ',arr.ndim)
print('~    ~    ~   shape: ',arr.shape)
print('~    ~    ~   size: ', arr.size)

# 輸出結果:
[[1 2 3]
 [4 5 6]]
number of arr dimensions:  2
~    ~    ~   shape:  (2, 3)
~    ~    ~   size:  6

numpy 數組增加列,增加行的函數:column_stack,row_stack

參數爲元組

a.column_stack((a, b))

定義一些特殊矩陣

# 指定矩陣數據類型
arr=np.array([[1,2,3],
              [4,5,6]],
              dtype=np.float64) # 我的電腦np.int是int32,還可以使用np.int32/np.int64/np.float32/np.float64
print(arr.dtype)

# 用np.zeros()生成全零矩陣
arr_zeros=np.zeros( (2,3) )
print(arr_zeros)

# 用np.ones()生成全一矩陣
arr_ones=np.ones( (2,3) )
print(arr_ones)

# 生成隨機矩陣np.random.random()
arr_random=np.random.random((2,3))
print(arr_random)

# 用np.arange()生成數列
arr=np.arange(6,12)
print(arr)

# 用np.arange().reshape()將數列轉成矩陣
arr=np.arange(6,12).reshape( (2,3) )
print(arr)

# 用np.linspace(開始,結束,多少點劃分線段),同樣也可以用reshape()
arr=np.linspace(1,5,3)
print(arr)

 

5.3.3 隨機模塊(random)

設置隨機數種子
random.seed(42)
#產生一個1x3,[0,1)之間的浮點型隨機數

#array([[ 0.37454012,  0.95071431,  0.73199394]])

#後面的例子就不在註釋中給出具體結果了
random.rand(1,3)


# 產生一個[0,1)之間的浮點型隨機數

random.random()
#下邊4個沒有區別,都是按照指定大小產生[0,1)之間的浮點型隨機數array,不Pythonic…
random.random((3,3))

random.sample((3,3))
random.random_sample((3,3))
random.ranf((3,3))
#產生10個[1,6)之間的浮點型隨機數

5*random.random(10)+1

random.uniform(1,6,10)

#產生10個[1,6]之間的整型隨機數

random.randint(1,6,10)


#產生2x5的標準正態分佈樣本random.normal(size=(5,2))
# 產生5個,n=5,p=0.5的二項分佈樣本
random.binomial(n=5,p=0.5,size=5)
a=np.arange(10)


# 從a中有回放的隨機採樣7個
random.choice(a,7)



# 從a中無回放的隨機採樣7個
random.choice(a,7,replace=False)
 對a進行亂序並返回一個新的array
b=random.permutation(a)


 對a進行in-place亂序
random.shuffle(a)
 生成一個長度爲9的隨機bytes序列並作爲str返回
 '\x96\x9d\xd1?\xe6\x18\xbb\x9a\xec'
random.bytes(9)


 

矩陣運算

# 矩陣運算
arr1=np.array([1,2,3,6])
arr2=np.arange(4)

# 矩陣減法,加法同理
arr_sub=arr1-arr2
print(arr1)
print(arr2)
print(arr_sub)

# 矩陣乘法
arr_multi=arr1**3 # 求每個元素的立方,在python中冪運算用**來表示
print(arr_multi)

arr_multi=arr1*arr2 # 元素逐個相乘
print(arr_multi) 

arr_multi=np.dot(arr1, arr2.reshape((4,1))) # 維度1*4和4*1矩陣相乘
print(arr_multi)

arr_multi=np.dot(arr1.reshape((4,1)), arr2.reshape((1,4))) # 維度4*1和1*4矩陣相乘
print(arr_multi)

arr_multi=arr1.dot(arr2.reshape((4,1))) # 也可以使用矩陣名.doc(矩陣名)
print(arr_multi)

# 三角運算:np.sin()/np.cos()/np.tan()
arr_sin=np.sin(arr1)
print(arr_sin)

# 邏輯運算
print(arr1<3) # 查看arr1矩陣中哪些元素小於3,返回[ True  True False False]

# 矩陣求和,求矩陣最大最小值
arr1=np.array([[1,2,3],
               [4,5,6]])
print(arr1)
print(np.sum(arr1)) # 矩陣求和
print(np.sum(arr1,axis=0)) # 矩陣每列求和
print(np.sum(arr1,axis=1).reshape(2,1)) # 矩陣每行求和

print(np.min(arr1)) # 求矩陣最小值
print(np.min(arr1,axis=0))
print(np.min(arr1,axis=1))

print(np.max(arr1)) # 求矩陣最大值

print(np.mean(arr1)) # 輸出矩陣平均值,也可以用arr1.mean()
print(np.median(arr1)) # 輸出矩陣中位數

# 輸出矩陣某些值的位置
arr1=np.arange(2,14).reshape((3,4))
print(arr1)

print(np.argmin(arr1)) # 輸出矩陣最小值的位置,0
print(np.argmax(arr1)) # 輸出矩陣最大值的位置,11

print(np.cumsum(arr1)) # 輸出前一個數的和,前兩個數的和,等等
print(np.diff(arr1)) # 輸出相鄰兩個數的差值

arr_zeros=np.zeros((3,4))
print(np.nonzero(arr_zeros)) #輸出矩陣非零元素位置,返回多個行向量,第i個行向量表示第i個維度
print(np.nonzero(arr1))

print(np.sort(arr1)) # 矩陣逐行排序
print(np.transpose(arr1)) # 矩陣轉置,也可以用arr1.T

print(np.clip(arr1,5,9)) #將矩陣中小於5的數置5,大於9的數置9

numpy索引

# numpy索引
arr1=np.array([1,2,3,6])
arr2=np.arange(2,8).reshape(2,3)

print(arr1)
print(arr1[0]) # 索引從0開始計數

print(arr2)
print(arr2[0][2]) # arr[行][列],也可以用arr[行,列]
print(arr2[0,:]) # 用:來代表所有元素的意思
print(arr2[0,0:3]) # 表示輸出第0行,從第0列到第2列所有元素
                   # 注意python索引一般是左閉右開

# 通過for循環每次輸出矩陣的一行
for row in arr2:
    print(row)

# 如果要每次輸出矩陣的一列,就先將矩陣轉置
arr2_T=arr2.T
print(arr2_T)
for row in arr2_T:
    print(row)

# 將矩陣壓成一行逐個輸出元素
arr2_flat=arr2.flatten()
print(arr2_flat)

for i in arr2.flat: # 也可以用arr2.flatten()
    print(i)

矩陣合併與分割

# 矩陣合併
arr1=np.array([1,2,3,6])
arr2=np.arange(4)
arr3=np.arange(2,16+1,2).reshape(2,4)
print(arr1)
print(arr2)
print(arr3)

arr_hor=np.hstack((arr1,arr2)) # 水平合併,horizontal
arr_ver=np.vstack((arr1,arr3)) # 垂直合併,vertical
print(arr_hor)
print(arr_ver)

# 矩陣分割
print('arr3: ',arr3)
print(np.split(arr3,4,axis=1)) # 將矩陣按列均分成4塊
print(np.split(arr3,2,axis=0)) # 將矩陣按行均分成2塊
print(np.hsplit(arr3,4)) # 將矩陣按列均分成4塊
print(np.vsplit(arr3,2)) # 將矩陣按行均分成2塊
print(np.array_split(arr3,3,axis=1)) # 將矩陣進行不均等劃分

numpy複製:淺複製,深複製

# numpy複製:淺複製,深複製
# 淺複製
arr1=np.array([3,1,2,3])
print(arr1)
a1=arr1
b1=a1
# 通過上述賦值運算,arr1,a1,b1都指向了同一個地址(淺複製)
print(a1 is arr1)
print(b1 is arr1)
print(id(a1))
print(id(b1))
print(id(arr1))

# 會發現通過b1[0]改變內容,arr1,a1,b1的內容都改變了
b1[0]=6
print(b1)
print(a1)
print(arr1)

# 深複製
arr2=np.array([3,1,2,3])
print('\n')
print(arr2)
b2=arr2.copy() # 深複製,此時b2擁有不同於arr2的空間
a2=b2.copy()
# 通過上述賦值運算,arr1,a1,b1都指向了不同的地址(深複製)
print(id(arr2))
print(id(a2))
print(id(b2))
# 此時改變b2,a2的值,互不影響
b2[0]=1
a2[0]=2
print(b2)
print(a2)
print(arr2)

線性代數模塊(linalg)

# 線性代數模塊(linalg)
# 求範數
a=np.array([5,12])
print(a)
b=np.linalg.norm(a) # norm表示範數,默認求2範數,ord=1求1範數,ord=np.inf求無窮範數
print(b)

# 求矩陣的跡、行列式、秩、特徵值、特徵向量
b = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

print(np.trace(b))      # 15,求矩陣的跡(主對角線上各個元素的總和)

c=np.linalg.det(b)
print(c)                # 輸出一個很小的值6.66133814775e-16,求矩陣的行列式值
                        # 如果希望輸出爲0,使用round(c, 2),四捨五入保留小數點後兩位
                        # 不過對精度要求高可以使用decimal模塊

c=np.linalg.matrix_rank(b)
print(c)                # 2,求矩陣的秩

u,v=np.linalg.eig(b) # u爲特徵值
print(u)
print(v)

# 矩陣分解
# Cholesky分解並重建
d = np.array([
    [2, 1],
    [1, 2]
])

l = np.linalg.cholesky(d)
print(l) # 得到下三角矩陣
e=np.dot(l, l.T)
print(e) # 重建得到矩陣d


# 對不正定矩陣,進行SVD分解並重建
U, s, V = np.linalg.svd(d)

S = np.array([
    [s[0], 0],
    [0, s[1]]
])

print(np.dot(U, np.dot(S, V))) # 重建得到矩陣d

# 矩陣乘法
# https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html#numpy.dot
print(np.dot(3, 4)) # 12,0-D矩陣相乘(也就是標量相乘)

print(np.dot([2j, 3j], [2j, 3j])) # (-13+0j),1-D矩陣相乘(實際上是向量做點積)

a=[[1, 0], [0, 1]]
b=[[4, 1, 0], [2, 2, 0]]
print(np.dot(a, b))
'''
array([[4, 1],
    [2, 2]])
2-D矩陣相乘
這裏是2*2矩陣和2*3矩陣相乘,結果爲2*3矩陣
'''

a=[[1, 0], [1, 2]]
b=[2,2]
c=np.dot(a,b)
print(c) 
'''
[2 6]
注意這裏b是向量
numpy處理時並不是按照矩陣乘法規則計算
而是向量點積
也就是np.dot([1, 0],[1, 2])和np.dot([1, 2],[2,2])
'''

# 再做個實驗來區別向量乘法和矩陣乘法
b=np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])

# 這裏插播一下,np.array([1,0,1])是3維向量,而不是1*3的矩陣
c1=np.array([[1,0,2]]) 
print(c1.shape) # (1, 3),這是一個1*3的矩陣
c2=np.array([1,0,2])
print(c2.shape) # (3,),這是一個3維向量

# print(np.dot(b,c1)) # 報錯,不符合矩陣乘法規則
print(np.dot(b,c2)) # [ 7 16 25],點積運算

print(np.dot(c1,b)) # [[15 18 21]],矩陣乘法運算規則
print(np.dot(c2,b)) # [15 18 21],點積運算

# 還要補充一下,如果是用python自帶的*運算符計算則是廣播機制
print(b*c1) # print(b*c2)結果一樣
'''
[[ 1  0  6]
 [ 4  0 12]
 [ 7  0 18]]
'''
print(b+c1) # print(b*c2)結果一樣
'''
[[ 2  2  5]
 [ 5  5  8]
 [ 8  8 11]]
'''
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章