numpy中一些常用的操作和用法

寫在前面

爲了方便查閱,本文爲作者閱讀代碼過程中在印象筆記中積累的筆記。幾乎每一項都有必要的代碼說明。由於比較長,讀者可以使用 Ctrl+F 鍵來實現快速的關鍵詞查找,文章的開頭部分也給出了索引。其中小部分內容可能有摘自其他優秀博客的解釋,不過由於時間比較久難以定位和溯源,之後如果看到會添加來源鏈接和作者。如果有需要pdf版的也可以留下郵箱。本文作爲方便查閱的筆記存在,因而會不定期更新。

numpy基本加減和取行操作

>>> import numpy as np
>>> a = np.array([1,1,1,1])
>>> b = np.array([[1],[1],[1],[1]])
>>> a+b
array([[2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2]])  # 這叫python的廣播機制
>>> c = np.array([[1,1,1,1]])
>>> c+b
array([[2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2],
       [2, 2, 2, 2]])

>>> W = np.array([[1,1,1],[2,2,2]])
>>> W[:,1]
array([1, 2]) # 這裏要特別注意,W[:,1]雖然取的是W的第一列,但是返回的卻是一維數組
>>> W[1]
array([2, 2, 2]) # 取得是W第一行,返回的也是一維數組
>>> W[:,1] = np.array([5,5])
>>> W
array([[1, 5, 1],
       [2, 5, 2]])  # 這裏用array[5,5]這樣的一維數組直接可以把W矩陣的第1列替換(維度符合即可)

矩陣刪除、插入、尾部添加操作(delete,insert,append)

numpy矩陣操作主要有delete()、insert()、append()等函數,分別執行刪除、插入和添加的操作,注意append可以看爲insert函數的特殊情況,即在尾部補充可以看爲插入最後一行或列,這在後文會舉例說明。

delete()函數

#numpy.delete(arr,obj,axis=None)
#axis 表明哪個維度的向量應該被移除
#axis 如果爲None,則需要先將矩陣拉平,在刪去第obj的元素
#obj 表明axis維度的哪一行(或列)應該被移除。

舉例說明如下

import numpy as np
matrix = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]
]
p1 = np.delete(matrix, 1, 0) # 第0維度(行)第1行被刪除(初始行爲0行)
print('>>>>p1>>>>\n',p1)
p2 = np.delete(matrix, 1, 1) # 第1維度(列)第1行被刪除
print('>>>>p2>>>>\n',p2)
p3 = np.delete(matrix, 1) # 拉平後刪除第1個元素(初始爲第0個)
print('>>>>p3>>>>\n',p3)
p4 = np.delete(matrix, [0,1], 1) # 第1維度(列)第0、1行被刪除
print('>>>>p4>>>>\n',p4) 
結果:
>>>>p1>>>>
 [[ 1  2  3  4]
 [ 9 10 11 12]]
>>>>p2>>>>
 [[ 1  3  4]
 [ 5  7  8]
 [ 9 11 12]]
>>>>p3>>>>
 [ 1  3  4  5  6  7  8  9 10 11 12]
>>>>p4>>>>
 [[ 3  4]
 [ 7  8]
 [11 12]]

insert()函數

#numpy.insert(arr,obj,value,axis=None)
#value 爲插入的數值
#arr 爲目標向量
#obj 爲目標向量的axis維度的目標位置
#axis 爲想要插入的維

舉例如下

import numpy as np
matrix = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]
]
q1 = np.insert(matrix, 1, [1,1,1,1], 0) # 第0維度(行)第1行添加[1,1,1,1]
print('>>>>q1>>>>\n',q1)
q2 = np.insert(matrix, 0, [1,1,1], 1) # 第1維度(列)第0列添加[1,1,1](列)
print('>>>>q2>>>>\n',q2)
q3 = np.insert(matrix, 3, [1,1,1,1], 0) # 第0維度(行)第3行添加[1,1,1,1]
print('>>>>q3>>>>\n',q3)
>>>>q1>>>>
 [[ 1  2  3  4]
 [ 1  1  1  1]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>>>q2>>>>
 [[ 1  1  2  3  4]
 [ 1  5  6  7  8]
 [ 1  9 10 11 12]]
>>>>q3>>>>
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [ 1  1  1  1]]

append()函數

#numpy.append(arr,values,axis=None)
#將values插入到目標arr的最後,其中values與arr應該有相同維度,具體見例子

import numpy as np
matrix = [
    [1,2,3,4],
    [5,6,7,8],
    [9,10,11,12]
]
m1 = np.append(matrix,[[1,1,1,1]],axis=0)
# 第0維度(行)尾部添加[[1,1,1,1]],注意兩個[],相同維度
print('>>>>m1>>>>\n',m1)
m2 = np.append(matrix,[[1],[1],[1]],axis=1)
# 第1維度(列)尾部添加[[1],[1],[1]],注意兩個[],相同維度
print('>>>>m2>>>>\n',m2)
m3 = np.append(matrix,[1,1,1,1])
# 拉平後再尾部添加[1,1,1,1],這裏可以[[1,1,1,1]]和[1,1,1,1]均可
print('>>>>m3>>>>\n',m3)
>>>>m1>>>>
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]
 [ 1  1  1  1]]
>>>>m2>>>>
 [[ 1  2  3  4  1]
 [ 5  6  7  8  1]
 [ 9 10 11 12  1]]
>>>>m3>>>>
 [ 1  2  3  4  5  6  7  8  9 10 11 12  1  1  1  1]

需要注意的是m1 = np.append(matrix,[[1,1,1,1]],axis=0) 與 q3 = np.insert(matrix, 3, [1,1,1,1], 0)結果一致,尾部添加即爲最後行或列的插入操作。

np.random.choice(a, size, replace, p)

其作用是按要求生成一個一維數組
a是生成一維數組的來源,可以是int類型,可以是數組,也可以是list
size 數組的維度
replace 表示從a中是否不重複抽取,默認可重複
p 給出抽取概率,默認隨機
注意 :這裏是圍繞數組展開的,如果提取的也是list,可以用 from random import choice 的 choice,可用 from random import sample 隨機抽取一組元素

>>> import numpy as np
>>> a1 = np.random.choice(7,5) # 從0~7中隨機選擇5個數組成一維數組
>>> a1
array([3, 1, 0, 1, 4])
>>> a2 = np.random.choice([0,1,2,3,4,5,6],5) # 從給定list中隨機選擇5個數組成一維數組
>>> a2
array([1, 6, 6, 6, 4])
>>> a3 = np.random.choice(np.array([0,1,2,3,4,5,6]),5) # 將list換成array數組依然可以運行,效果一致
>>> a3
array([3, 0, 5, 5, 3])
>>> a4 = np.random.choice([0,1,2,3,4,5,6],5,replace=False) # 上述均有重複,將replace設置爲False,即可按要求沒有重複的選取
>>> a4
array([0, 4, 3, 6, 5])
>>> a5 = np.random.choice(np.array([0,1,2,3,4,5,6]),5,p=[0.1,0.1,0.1,0.1,0.1,0.1,0.4]) 
# 給出選取概率p,注意p的維度和a的維度一致,並且p中概率和爲1
>>> a5
array([6, 3, 2, 6, 6])

np.argmax(a, axis=None, out=None)

作用是返回軸的最大值的索引值
a:需要操作的數組或者矩陣,默認情況拉平成數組
axis:默認將a拉平,當axis=0對a按列取最大值索引,axis=1則對a按行取最大值索引
out:將結果寫到a中

>>> import numpy as np
>>> a = np.array([[1,1,1],[2,2,2],[0,3,6]])
>>> a
array([[1, 1, 1],
       [2, 2, 2],
       [0, 3, 6]])
>>> b1 = np.argmax(a) # 將數組a拉平,最大值索引爲9(初始索引爲0)
>>> b1
8
>>> b2 = np.argmax(a, axis=0) # 按列選取最大值的索引
>>> b2
array([1, 2, 2], dtype=int64)
>>> b3 = np.argmax(a, axis=1) # 按行選取最大值的索引
>>> b3
array([0, 0, 2], dtype=int64)

星號(*)的作用

列表前加星號作用是將列表解開成兩個獨立的參數,輸入函數。
字典前加兩個星號,是將字典解開成獨立的元素作爲形參。


ndarray.ndim代表的就是shape元組的長度。


numpy.linspace用法

numpy.linspace(start, shop, num==50, endpoint=True, retstep=False, dtype=None)
在指定間隔start到stop內返回均勻間隔的數組。
返回num均勻分佈的樣本,在[start, stop],默認生成50個數據
endpoint, 如果是真,則一定包括stop,如果爲False,一定不會有stop
retstep,是否顯示步長信息

>>> import numpy as np
>>> y1 = np.linspace(-10.0,10.0) # 默認生成50個數據
>>> y1
array([-10.        ,  -9.59183673,  -9.18367347,  -8.7755102 ,
        -8.36734694,  -7.95918367,  -7.55102041,  -7.14285714,
        -6.73469388,  -6.32653061,  -5.91836735,  -5.51020408,
        -5.10204082,  -4.69387755,  -4.28571429,  -3.87755102,
        -3.46938776,  -3.06122449,  -2.65306122,  -2.24489796,
        -1.83673469,  -1.42857143,  -1.02040816,  -0.6122449 ,
        -0.20408163,   0.20408163,   0.6122449 ,   1.02040816,
         1.42857143,   1.83673469,   2.24489796,   2.65306122,
         3.06122449,   3.46938776,   3.87755102,   4.28571429,
         4.69387755,   5.10204082,   5.51020408,   5.91836735,
         6.32653061,   6.73469388,   7.14285714,   7.55102041,
         7.95918367,   8.36734694,   8.7755102 ,   9.18367347,
         9.59183673,  10.        ])
>>> y2 = np.linspace(1,10,10) # 生成10個數據,包括首尾
>>> y2
array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
>>> y3 = np.linspace(1,10,10,endpoint=False) # 不包括尾部數據
>>> y3
array([1. , 1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1])
>>> y4= np.linspace(1, 10, 6, retstep=True) # 將步長與結果的數組放入一個list、
>>> y4
(array([ 1. ,  2.8,  4.6,  6.4,  8.2, 10. ]), 1.8)

拉平操作 ravel()和faltten()及reshape(1,-1)的區別聯繫(補充[None,:]操作)

都是對numpy矩陣進行拉平處理,區別在於flatten()返回的僅僅是copy值,而ravel()返回的是實際的值,有點返回地址的意思。而x.reshape(1,-1)表示把向量 x reshape成一個行向量,注意的它仍然保持x的維度。
另外,Numpy中的 一維向量 有個特殊的用法,將行或者列設置成None,用來將矩陣轉換成行或者列。偶爾會看到np.newaxis,這與None用法一致。
詳見代碼

>>> import numpy as np
>>> x = np.array([[1,2,3],[4,5,6],[1,2,3]])
>>> x.flatten()
array([1, 2, 3, 4, 5, 6, 1, 2, 3]) # 拉平
>>> x.ravel()
array([1, 2, 3, 4, 5, 6, 1, 2, 3])
>>> x.ravel('F')
array([1, 4, 1, 2, 5, 2, 3, 6, 3]) # 按列拉平
>>> x.flatten('F')
array([1, 4, 1, 2, 5, 2, 3, 6, 3])
>>> x.flatten()[1] = 20
>>> x
array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3]])
>>> x.ravel()[1] = 20
>>> x
array([[ 1, 20,  3],
       [ 4,  5,  6],
       [ 1,  2,  3]])
>>> x.reshape(1,-1) # 注意結果仍然是二維
array([[1, 2, 3, 4, 5, 6, 1, 2, 3]]) # 這裏有兩個方括號
>>> x = np.array([1,2,3,6,7,8]) # 注意操作的是數組,即原x是數組
>>> x[None,:]  # 轉成行向量(二維矩陣)
array([[1, 2, 3, 6, 7, 8]])
>>> x[:,None] # 轉成列向量(二維矩陣)
array([[1],
       [2],
       [3],
       [6],
       [7],
       [8]])
>>> x[np.newaxis, :] # np.newaxis與None用法一致
array([[1, 2, 3, 6, 7, 8]])

np.prod() 計算元素乘積

默認計算矩陣所有元素的乘積,也可以通過axis計算指定軸的乘積

>>> x = np.array([[1,2,3],[2,3,4]])
>>> np.prod(x)
144
>>> np.prod(x,axis=1)
array([ 6, 24])
>>> np.prod(x,axis=0)
array([ 2,  6, 12])

把矩陣大於或小於N的元素置M的技巧

技巧包括 maximum() 函數 、minimum() 函數,以及 矩陣操作的技巧

>>> import numpy as np
>>> x = np.array([[1,2,3],[-3,2,4],[5,-2,9]])
>>> x
array([[ 1,  2,  3],
       [-3,  2,  4],
       [ 5, -2,  9]])
>>> y1 = np.maximum(0,x) # 把小於0的元素置0,比改變x的值
>>> y1
array([[1, 2, 3],
       [0, 2, 4],
       [5, 0, 9]])
>>> y2 = np.minimum(0,x) # 把大於0的元素置0,不改變x的值
>>> y2
array([[ 0,  0,  0],
       [-3,  0,  0],
       [ 0, -2,  0]])
>>> x1 = x.copy() 
>>> x1
array([[ 1,  2,  3],
       [-3,  2,  4],
       [ 5, -2,  9]])
>>> x1[x1 < 0] = 0 # 把小於0的元素置0,改變x1的值
>>> x1
array([[1, 2, 3],
       [0, 2, 4],
       [5, 0, 9]])
>>> x2 = x.copy()
>>> x2[x2 > 0] = 0 # 把大於0的元素置0,改變x2的值
>>> x2
array([[ 0,  0,  0],
       [-3,  0,  0],
       [ 0, -2,  0]])

numpy中的矩陣copy問題

還記得Python的可變可不變對象不,簡單溫習一下:
不可變對象: 該對象所指向的內存中的值不能被改變。當改變某個變量的時候,由於其所指的值不能被改變,相當於把原來的值複製一份後再改變,這會開闢一個新的地址,變量再指向這個地址。
不可變對象包括 int string float tuple None
可變對象: 該對象所指向的內存中的值可以被改變。變量(準確說是引用)被改變後,實際上是其所指的值直接發生改變,並沒有發生複製行爲,也沒有開闢新的地址,通俗點說就是原地改變。
可變對象包括 list dictionary set
numpy的narray用法就類似於可變對象,直接等於並不會開闢新的地址,改變賦值對象也就改變了原來的值。舉例如下:

>>> import numpy as np
>>> x = np.array([[1,2,3],[-3,2,4],[5,-2,9]])
>>> x
array([[ 1,  2,  3],
       [-3,  2,  4],
       [ 5, -2,  9]])
>>> x1 = x.copy() # copy(),開闢新地址
>>> x1[x1 > 0] = 0
>>> x1
array([[ 0,  0,  0],
       [-3,  0,  0],
       [ 0, -2,  0]])
>>> x # x不變
array([[ 1,  2,  3],
       [-3,  2,  4],
       [ 5, -2,  9]])
>>> x2 = x # 直接等於,未開闢新地址,x2與x相關聯
>>> x2
array([[ 1,  2,  3],
       [-3,  2,  4],
       [ 5, -2,  9]])
>>> x2[x2>0] = 0
>>> x2
array([[ 0,  0,  0],
       [-3,  0,  0],
       [ 0, -2,  0]])
>>> x # x也改變
array([[ 0,  0,  0],
       [-3,  0,  0],
       [ 0, -2,  0]])   
>>> x = np.array([[1,2,3],[-3,2,4],[5,-2,9]])
>>> x3 = x[2] # 取x的第3行
>>> x3
array([ 5, -2,  9])
>>> x3[2] = 100 # 將x3第3個元素置100
>>> x # x中對應的元素置也被置成100了
array([[  1,   2,   3],
       [ -3,   2,   4],
       [  5,  -2, 100]])

np.zeros_like()構造全零矩陣,無需指定大小

>>> import numpy as np
>>> x = np.array([[1,2,3],[4,5,6]])
>>> np.zeros_like(x) # 生成一個和x大小相同的全零矩陣
array([[0, 0, 0],
       [0, 0, 0]])

random.rand和random.rand和random.randint區別

np.random.random() 生成一個隨機數

產生 0 ~ 1 之間的隨機浮點數,無輸入參數

np.random.uniform()

產生隨機浮點數

np.random.rand() 生成均勻分佈矩陣

創建一個矩陣,服從[0,1]隨機分佈

>>> import numpy as np
>>> n = np.random.rand(3,4)
>>> n
array([[0.11502462, 0.3503468 , 0.6206656 , 0.35172063],
       [0.66367565, 0.10195004, 0.22708003, 0.9318615 ],
       [0.77946053, 0.81804715, 0.2272248 , 0.17736476]])

np.random.randn() 生成正太分佈矩陣

創建一個矩陣,服從N(0,1)標準正太分佈。
一般正太分佈N=(μ,σ2)N=(\mu ,\sigma^2)可通過 sigma * np.random.randn(…) + m 實現

>>> import numpy as np
>>> x = np.random.randn(2,3)
>>> x
array([[-0.09382672, -0.97939614,  0.0222352 ],
       [ 0.15060188, -0.01107968,  1.08374427]])
>>> y = np.multiply(0.1,np.random.randn(2,3))+0.5 # 一般正太分佈
>>> y
array([[0.49305173, 0.36802044, 0.48699281],
       [0.45197275, 0.53837051, 0.60022348]])   

np.randm.randint() 生成離散均勻分佈的整數值組成的矩陣

numpy.random.randint(low,high=None,size=None,dtype)
生成半開半閉區間[low, high)上離散均勻分佈的整數值,未給出high時,區間變爲[0, low)

>>> import numpy as np
>>> z = np.random.randint(2,9,(2,3))
>>> z
array([[2, 3, 6],
       [8, 2, 8]])
>>> m = np.random.randint(9,size = (2,3))
>>> m
array([[4, 0, 2],
       [5, 2, 8]])

python 斷言 assert

>>> x = 'You are right'
>>> type(x)
<class 'str'>
>>> assert type(x)==str, 'x is not str'
>>> x = [1,2,3]
>>> type(x)
<class 'list'>
>>> assert type(x)==str, 'x is not str'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: x is not str

星號( * ) 和 .dot 和 np.multiply 的區別聯繫

A * B 表示 A 和 B 的對應元素相乘,其中 A 和 B 大小一致
np.multiply 與星號用法一致,均表示對應元素相乘
而 .dot 是矩陣運算中的點乘, A 的列數需要等於 B 的行數。


np.pad()函數進行padding操作

語法:

pad(array, pad_width, mode, **kwargs)返回值:數組

參數解釋:

array——表示需要填充的數組;
pad_width——表示每個軸(axis)邊緣需要填充的數值數目。
參數輸入方式爲:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1軸兩邊緣分別填充before_1個和after_1個數值。取值爲:{sequence, array_like, int}
mode——表示填充的方式(取值:str字符串或用戶提供的函數),總共有11種填充模式;

填充方式:

‘constant’——表示連續填充相同的值,每個軸可以分別指定填充值,constant_values=(x, y)時前面用x填充,後面用y填充,缺省值填充0
‘edge’——表示用邊緣值填充
‘linear_ramp’——表示用邊緣遞減的方式填充
‘maximum’——表示最大值填充
‘mean’——表示均值填充
‘median’——表示中位數填充
‘minimum’——表示最小值填充
‘reflect’——表示對稱填充
‘symmetric’——表示對稱填充
‘wrap’——表示用原數組後面的值填充前面,前面的值填充後面

#在數組A的邊緣填充constant_values指定的數值
#(3,2)表示在A的第[0]軸填充(二維數組中,0軸表示行),即在0軸前面填充3個寬度的0,比如數組A中的95,96兩個元素前面各填充了3個0;在後面填充2個0,比如數組A中的97,98兩個元素後面各填充了2個0
#(2,3)表示在A的第[1]軸填充(二維數組中,1軸表示列),即在1軸前面填充2個寬度的0,後面填充3個寬度的0
np.pad(A,((3,2),(2,3)),‘constant’,constant_values = (0,0)) #constant_values表示填充值,且(before,after)的填充值等於(0,0)

代碼示例:

import numpy as np
>>> A = np.arange(95,99).reshape(2,2)
>>> A 
array([[95, 96], [97, 98]])
>>> np.pad(A,((3,2),(2,3)),'constant',constant_values = (0,0))  
array([[ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 95, 96,  0,  0,  0],
       [ 0,  0, 97, 98,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0]])
說明: 在矩陣行的上部分添加3行,下部分添加2行,在列的左部分添加2列,右部分添加3列。
>>> b = np.array([[[1,2],[3,4]],[[3,4],[7,8]],[[4,5],[1,2]]])
>>>
>>> b
array([[[1, 2],
        [3, 4]],

       [[3, 4],
        [7, 8]],

       [[4, 5],
        [1, 2]]])
>>> np.pad(b, ((0,0),(1,1),(1,1)), 'constant', constant_values = 0)
array([[[0, 0, 0, 0],
        [0, 1, 2, 0],
        [0, 3, 4, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 3, 4, 0],
        [0, 7, 8, 0],
        [0, 0, 0, 0]],

       [[0, 0, 0, 0],
        [0, 4, 5, 0],
        [0, 1, 2, 0],
        [0, 0, 0, 0]]])

numpy.empty() 創建指定形狀和數據類型且未初始化的數組

numpy.empty 方法用來創建一個指定形狀(shape)、數據類型(dtype)且未初始化的數組

numpy.empty(shape, dtype = float, order = 'C')

shape數組形狀
dtype數據類型,可選
order有"C"和"F"兩個選項,分別代表,行優先和列優先,在計算機內存中的存儲元素的順序。

import numpy as np 
x = np.empty([3,2], dtype = int) 
print (x)

輸出:
[[ 6917529027641081856  5764616291768666155]
 [ 6917529027641081859 -5764598754299804209]
 [          4497473538      844429428932120]]

數組元素爲隨機值,因爲它們未初始化。


判斷兩個矩陣元素完全相等&&存在相等

(ab).all() 判斷是否完全相等
(a
b).any() 判斷是否存在元素相等

a = np.array([[1,2,3][1,2,3]])
b = np.array([[1,2,3][1,2,3]])
c = np.array([[1,4,3][1,2,3]])
print((a==b).all())    # 是否完全相等 True
print((a==c).all())    # False
print((a==c).any())  # 是否存在元素相等 True  

關於 np.mat() 的使用

  • np.array() 更具有通用性,np.mat 只適用於二維矩陣
  • np.mat() 和 np.matrix() 都可以將 list 轉換爲 numpy.matrix 類型的矩陣,而 np.array() 不行

np.full 用於形成元素全爲某元素的矩陣

np.full(shape, val): 生成形爲 shape 的元素全爲 val 的矩陣


astype 轉換數據類型

>>> import numpy as np
>>> c = np.array([[1,2],[3,4]])
>>> c
array([[1, 2],
       [3, 4]])
>>> c.astype(np.float32)
array([[1., 2.],
       [3., 4.]], dtype=float32)

np.meshgrid() 快速生成網格

meshgrid(x,y) 可用於快速生成由於 x軸座標 x 和 y 軸座標 y 組合的網格點

>>> import numpy as np
>>> x = np.array([1,3,5])
>>> y = np.array([4,6])
>>> XX,YY = np.meshgrid(x,y)
>>> XX
array([[1, 3, 5],
       [1, 3, 5]])
>>> YY
array([[4, 4, 4],
       [6, 6, 6]])
# 這樣就組合成 (1,4) (3,4) (5,4) (1,6) (3,6) (5.6)  的網格點

np.hstack() 和 np.vstack() 用於堆疊矩陣

注意下面的 M 是 tuple 形式,如 (x,y),x和y均爲 np.array 形式的矩陣
np.vstack(M) 用於沿着豎直方向將矩陣堆疊起來
np.hstack(M) 用於沿着水平方向將矩陣堆疊起來

>>> import numpy as np
>>> x = np.array([[3,4,5],[1,3,4]])
>>> y = np.array([[1,1,1],[2,2,2]])
>>> np.hstack((x,y)) # 水平堆疊
array([[3, 4, 5, 1, 1, 1],
       [1, 3, 4, 2, 2, 2]])
>>> np.vstack((x,y)) # 豎直堆疊
array([[3, 4, 5],
       [1, 3, 4],
       [1, 1, 1],
       [2, 2, 2]])

numpy 取整

np.round 和 np.around 一致,均是四捨五入運算,默認取整,可通過 decimals 調整小數位數
np.floor 是向下取整操作
np.ceil 是向上取整操作

>>> import numpy as np
>>> a = np.array([0.125,0.568,5.688])
>>> np.round(a) # 四捨五入取整, np.around 和 round 用法一致
array([0., 1., 6.])
>>> np.round(a,decimals = 2) # 四捨五入保留2位小數
array([0.12, 0.57, 5.69])
>>> np.floor(a) # 向下取整
array([0., 0., 5.])
>>> np.ceil(a) # 向上取整
array([1., 1., 6.])

np.newaxis 在特定位置增加一個維度

記着 c[:,np.newaxis] 是將矩陣c再加一個維度,如果c是一維的,那麼這個表達式是將 c 變成列向量, c[np.newaxis,:] 是將矩陣 c 變成行向量。
看例子

>>> import numpy as np
>>> c = np.array([1,2,5,4])
>>> c[:,np.newaxis]
array([[1],
       [2],
       [5],
       [4]])
>>> c[np.newaxis,:]
array([[1, 2, 5, 4]])

python 廣播機制

Numpy要求輸入的數組shape一致,當shape不一致的時候,則會使用廣播機制,調整數組的shape一致,否則出錯。
廣播機制的四條規則如下:

  • 讓所有輸入數組都向其中shape最長的數組看齊,shape中不足的部分都通過在前面加1補齊
  • 輸出數組的shape是輸入數組shape的各個軸上的最大值
  • 如果輸入數組的某個軸和輸出數組的對應軸的長度相同或者其長度爲1時,這個數組能夠用來計算,否則出錯
  • 當輸入數組的某個軸的長度爲1時,沿着此軸運算時都用此軸上的第一組值
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a = np.array([[1,2,3,6],[4,5,6,6]])
>>> a1 = a.reshape((1,2,4))
>>> a1
array([[[1, 2, 3, 6],
        [4, 5, 6, 6]]])
>>> b = np.array([[3,4,5,6],[1,2,3,4],[4,5,5,5]])
>>> b
array([[3, 4, 5, 6],
       [1, 2, 3, 4],
       [4, 5, 5, 5]])
>>> b1 = b.reshape((1,3,4)).transpose((1,0,2))
>>> b1
array([[[3, 4, 5, 6]],

       [[1, 2, 3, 4]],

       [[4, 5, 5, 5]]])
>>> a1
array([[[1, 2, 3, 6],
        [4, 5, 6, 6]]])
>>> a1+b1
array([[[ 4,  6,  8, 12],
        [ 7,  9, 11, 12]],

       [[ 2,  4,  6, 10],
        [ 5,  7,  9, 10]],

       [[ 5,  7,  8, 11],
        [ 8, 10, 11, 11]]])

上面這個例子中,a1 是 [1,2,4] 維度的數組,b1 是 [3,1,4] 維度的數組,可以如此理解,他們相加後由於廣播機制的作用應該生成 [3,2,4] 大小的數組。那麼我們將 a1 擴展成 [3,2,4] 成

[[[1, 2, 3, 6],
[4, 5, 6, 6]],
[[1, 2, 3, 6],
[4, 5, 6, 6]],
[[1, 2, 3, 6],
[4, 5, 6, 6]]]

將 b1 擴展成 [3,2,4] 成

[[[3, 4, 5, 6],
[3, 4, 5, 6]],
[[1, 2, 3, 4],
[1, 2, 3, 4]],
[[4, 5, 5, 5],
[4, 5, 5, 5]]]

擴展後的 a1 和 b1 相加得到

[[ 4, 6, 8, 12],
[ 7, 9, 11, 12]],
[[ 2, 4, 6, 10],
[ 5, 7, 9, 10]], 
[[ 5, 7, 8, 11],
[ 8, 10, 11, 11]]]

即爲通過廣播機制相加的結果。

詳見 Numpy中的廣播操作 https://blog.csdn.net/qq_36387683/article/details/80628577


numpy.transpose()轉置

transpose()是以交換維度的方式進行轉置。如

>>> c = np.array([[[1,2,5],[3,4,6]],[[4,5,6],[7,8,9]]])
>>> c
array([[[1, 2, 5],
        [3, 4, 6]],

       [[4, 5, 6],
        [7, 8, 9]]])
>>> c.transpose(1,0,2) # 將c的維度按照 第1維度,第0維度,第2維度的排序排成 第0,1,2維度
array([[[1, 2, 5],
        [4, 5, 6]],

       [[3, 4, 6],
        [7, 8, 9]]])
如原來的 4 (4,5,6的4)本是 (1,0,0), 轉換後變爲 (0,1,0)
>>> c.transpose(1,2,0) # 將c的維度按照 第1維度,第2維度,第0維度的排序排成 第0,1,2維度
array([[[1, 4],
        [2, 5],
        [5, 6]],

       [[3, 7],
        [4, 8],
        [6, 9]]])
如原來的 4 (4,5,6的4)本是 (1,0,0), 轉換後變爲 (0,0,1)

常用來對 numpy 圖片矩陣作轉換

  • 在opencv中,圖片格式爲 H W C,即長寬和維度,而一般圖像處理的時候習慣用 C H W,故可以用 transpose 對維度進行變換
img = cv2.imread("111.jpg")
img_ = img[:,:,::-1] # cv2 讀取的是 BGR,::-1 將C通道按照RGB取反
img_convet = img_.transpose((2,0,1)) # 將 H W C 轉爲 C H W

numpy 中雙冒號的用法

numpy 中 ndarray 對象內容可以索引或切片來訪問和修改。可以通過 start:stop:step 來進行切片操作,如下

>>> import numpy as np
>>> a = np.array([2,2,3,4,5,5,6,7])
>>> a[0:7:2]
array([2, 3, 5, 6])

而雙冒號實則是兩個冒號之間缺省了必要的值,它省略的是 stop 值,那麼 stop 值就默認尾部。如下

>>> import numpy as np
>>> a = np.array([2,2,3,4,5,5,6,7])
>>> a[0::2]
array([2, 3, 5, 6])

除了一般的切片用法,也常用 [::-1] 來將序列按倒序排列。

>>> a[::-1]
array([7, 6, 5, 5, 4, 3, 2, 2])

一般而言,python 的內置函數 slice 就實現了此功能,用法是 slice(start, stop, step)。如

>>> import numpy as np
>>> a = np.array([2,2,3,4,5,5,6,7])
>>> s = slice(0,7,2)
>>> a[s]
array([2, 3, 5, 6])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章