Python3 NumPy基礎:數組和矢量計算

目錄

 

NumPy介紹:

部分功能如下:

ndarray:

創建ndarray:

ndarray的數據類類型:

數組和標量之間的運算:

數組之間的運算:

數組和標量之間的運算:

基本的索引和切片:

布爾型索引:

花式索引:

數組轉置和軸對換:

通用函數:快速的元素級數組函數:

一元函數:

二元函數:

利用數組進行數據處理:

將條件邏輯表述爲數組運算:

數學和統計方法:

用於布爾型數組的方法:

排序:

ndarray的基本集合運算:

用於數組的文件輸入輸出:

線性代數:

僞隨機數生成:


NumPy介紹:

NumPy是高性能科學計算和數據分析的基礎包。

部分功能如下:

  • ndarray,一個具有矢量算術運算和複雜廣播能力的快速且節省空間的多維數組
  • 用於對整組數據進行快速運算的標準數學函數(無需編寫循環)
  • 用於讀寫磁盤數據的工具以及用於操作內存映射文件的工具
  • 線性代數、隨機數生成以及傅里葉變換功能
  • 用於繼承C、C++、Fortran等語言編寫的代碼的工具

ndarray:

ndarray是一種多維數組對象,它的所有元素必須是相同類型的,每個數組都有一個shape(表示各維度大小的元組)和一個的dtype(表示數組數據類型的對象)

創建ndarray:

函數 說明
array 將輸入數據(列表、元組、數組或其他序列類型)轉換爲ndarray,可傳dtype參數指定數據類型,不傳dtype參數numpy會自動推斷數據類型。默認直接複製輸入數據。
asarray 將輸入轉換成ndarray,如果輸入本身就是ndarray就不進行復制
arange 類似於range,但返回的是一個ndarray不是生成器
ones、ones_like ones根據指定形狀(一個用來定義維度的元組)和dtype創建一個全1數組,ones_like以另一個ndarray數組爲參數,並根據形狀和dtype創建一個全1數組
zeros、zeros_like 類似於ones和ones_like,只不過返回的是全0數組
empty、empty_like 類似於ones和ones_like,之分配空間不填充任何數值(隨機數字)
eye、identity 創建一個正方的N×N單位矩陣(對角線爲1,其餘全爲0)

ndarray的數據類類型:

類型 類型代碼 說明
int8、uint8 i1、u1 有符號和無符號的8位(1字節)整型
int16、uint16 i2、u2 有符號和無符號的16位(2字節)整型
int32、uint32 i4、u4 有符號和無符號的32位(4字節)整型
int64、uint64 i8、u8 有符號和無符號的64位(8字節)整型
float16 f2 半精度浮點數
float32 f4或f 標準的單精度浮點數,與C的float兼容
float64 f8或d 標準的雙精度浮點數,與C的double和Python的float兼容
float128 f16或g 擴展精度浮點數
complex64、complex128、complex256 c8、c16、c32 分別用32位、64位和128位浮點數表示的複數
bool ? 存儲True和False的布爾類型
object O Python對象類型
string_ S 固定長度的字符串類型(每個字符一個字節)。例如,創建一個長度爲10的字符串應使用S10。
unicode_ U 固定長度的unicode類型(字節數由平臺決定)。和字符串定義方式一樣(如U10)

使用ndarray的astype方法可以轉換ndarray的數據類型。

In [28]: a1=array([1, 2, 3])

In [30]: a1.astype('S1')                                                                           
Out[30]: array([b'1', b'2', b'3'], dtype='|S1')

數組和標量之間的運算:

數組之間的運算:

大小相等的數組之間的任何算術運算都會應用到元素級。

In [35]: a1=np.arange(6).reshape((2,3)) 

In [38]: a1*a1                                                                                     
Out[38]: 
array([[ 0,  1,  4],
       [ 9, 16, 25]])

In [39]: a1+a1                                                                                     
Out[39]: 
array([[ 0,  2,  4],
       [ 6,  8, 10]])

 大小相同的數組之間的比較會生成布爾值數組:

In [57]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])

In [58]: arr2
Out[58]: 
array([[  0.,   4.,   1.],
       [  7.,   2.,  12.]])

In [59]: arr2 > arr
Out[59]:
array([[False,  True, False],
       [ True, False,  True]], dtype=bool)

數組和標量之間的運算:

數組與標量的運算會把標量值廣播到數組的每個元素。

In [40]: a1 / 1                                                                                     
Out[40]: 
array([[0., 1., 2.],
       [3., 4., 5.]])

In [41]: a1*2                                                                                      
Out[41]: 
array([[ 0,  2,  4],
       [ 6,  8, 10]])

 數組和標量的比較運算會生成一個與原數組相同維度的布爾型數組。

In [52]: a=np.arange(9).reshape(3,3)                                                               

In [53]: a                                                                                         
Out[53]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [54]: a>=5                                                                                      
Out[54]: 
array([[False, False, False],
       [False, False,  True],
       [ True,  True,  True]])

基本的索引和切片:

ndarray數組在某一個維度上的切片和普通list對象切片方法相同。([:],[0],[1:],[::2])

數組的切片是原數組的視圖不是複製出一個新數組。使用標量對數組的視圖賦值時會廣播到整個選區。需要真正意義上的複製一個數組應使用copy()方法。

以下兩種方式相同:

In [74]: a1[0][2]
Out[74]: 3

In [75]: a1[0, 2]
Out[75]: 3

布爾型索引:

使用一個數組和一個標量進行比較運算會得到一個布爾型數組,這個布爾型數組可以用於數組索引。

In [60]: index=np.array(['a','b','c','d']) 

In [62]: data=np.arange(24).reshape(4,6)                                                           

In [63]: data                                                                                      
Out[63]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

布爾型數組的長度必須跟被索引的軸長度一致。此外,還可以將布爾型數組跟切片、整數混合使用,可以通過~對條件進行否定,需要組合應用多個布爾條件,使用&(和)、|(或)之類的布爾算術運算符。

In [65]: data[(index=='a') | (index!='d')]                                                         
Out[65]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

通過布爾型索引選取數組中的數據,將總是創建數據的副本,即使返回一模一樣的數組也是如此。

但是對通過布爾型索引選取數組中的數據賦值,將廣播到整個索引選中的選區。

In [67]: data[index=='b']=1                                                                        

In [68]: data                                                                                      
Out[68]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 1,  1,  1,  1,  1,  1],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])

花式索引:

花式索引(Fancy indexing)是一個NumPy術語,它指的是利用整數數組進行索引。

用一個數組作爲索引,選取一個ndarray對象相應維度上指定順序的列表或ndarray對象,使用負數索引將會從末尾開始選取。

In [2]: a=np.arange(20).reshape(4,5)                                                               

In [3]: a                                                                                          
Out[3]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])

In [4]: a[[0,2]]                                                                                   
Out[4]: 
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14]])

用小於等於ndarray對象維度個數的整數數組做索引,所有維度對應的索引數組中長度大於1的索引數組長度必須相等。

In [29]: b=np.arange(27).reshape(3,3,3)                                                            

In [30]: b                                                                                         
Out[30]: 
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])

In [31]: b[[0,1,2],[1,1,2],[1]]                                                                    
Out[31]: array([ 4, 13, 25])

In [32]: b[[2],[1],[1,0,2]]                                                                        
Out[32]: array([22, 21, 23])

如果索引數組長度大於1的索引數組長度不相等,則會報出索引錯誤。

In [34]: b[[2,1,0],[2,2]]                                                                          
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-34-b0a6caf26928> in <module>
----> 1 b[[2,1,0],[2,2]]

IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,)

b[[0,1,2],[1,1,2],[1]]選取的是(0,1,1),(1,1,1,),(2,2,1),並不是像我們想的那樣是一個矩形區域。

可以使用下面這種方法選取一個矩形區域。

In [48]: b                                                                                         
Out[48]: 
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])

In [49]: b[[2,1,0]][:,[1]]                                                                         
Out[49]: 
array([[[21, 22, 23]],

       [[12, 13, 14]],

       [[ 3,  4,  5]]])

花式索引會把索引選取的數據複製到新數組中。

數組轉置和軸對換:

轉置是重塑的一種特殊形式,它返回的是源數據的視圖(不會進行任何複製操作)。數組不僅有transpose方法,還有一個特殊的T屬性。

ndarray數組的T屬性會返回shape是原數組的shape的倒序ndarray對象。

In [95]: d                                                                                         
Out[95]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]],

       [[16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [96]: d.shape                                                                                   
Out[96]: (3, 2, 4)

In [97]: d.T                                                                                       
Out[97]: 
array([[[ 0,  8, 16],
        [ 4, 12, 20]],

       [[ 1,  9, 17],
        [ 5, 13, 21]],

       [[ 2, 10, 18],
        [ 6, 14, 22]],

       [[ 3, 11, 19],
        [ 7, 15, 23]]])

In [98]: d.T.shape                                                                                 
Out[98]: (4, 2, 3)

ndarray數組的transpose需要得到一個由軸編號組成的元組才能對這些軸進行轉置。下面這個示例就是把0軸和1軸交換了,2軸沒有改變。

In [102]: d                                                                                        
Out[102]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]],

       [[16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [103]: d.transpose(1,0,2)                                                                       
Out[103]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11],
        [16, 17, 18, 19]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15],
        [20, 21, 22, 23]]])

 ndarray還有一個swapaxes方法,它需要接受一對軸編號。

In [104]: d                                                                                        
Out[104]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]],

       [[16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [105]: d.swapaxes(0,2)                                                                          
Out[105]: 
array([[[ 0,  8, 16],
        [ 4, 12, 20]],

       [[ 1,  9, 17],
        [ 5, 13, 21]],

       [[ 2, 10, 18],
        [ 6, 14, 22]],

       [[ 3, 11, 19],
        [ 7, 15, 23]]])

通用函數:快速的元素級數組函數:

一元函數:

函數 說明
abs,fabs 計算整數、浮點數或複數的絕對值。對於非複數值,可以使用更快的fabs
sqrt 計算各個元素的平方根。相當於arr**0.5
square 計算各個元素的平方。相當於arr**2
exp 計算各個元素的指數e^{x}
log、log10、log2、log1p 分別爲自然對數(底數爲e)、底數爲10的log、底數爲2的log、log(1+x)
sign 計算各個元素的正負號:1(整數)、0(零)、-1(負數)
ceil 計算各個元素的ceiling值,即大於等於該值的最小整數,向上取整
floor 計算各個元素的floor值,即小於等於該值的最大整數,向下取整
rint 將各個元素值四捨五入到最近的整數,保留dtype
modf 將數組的小數和整數部分以兩個獨立數組的形式返回
isnan 返回一個表示“那些值是NaN(不是數字)”的布爾型數組
isfinite、isinf 分別返回一個表示“表示哪些元素是有窮的”或“哪些元素是無窮的(inf)”的布爾型數組
cos、cosh、sin、sinh、tan、tanh 普通型和雙曲型三角函數
arccos、arccosh、arcsin、arcsinh、arctan、arctanh 反三角函數
logical_not 計算各個元素not x的真值,相當於-arr

二元函數:

函數 說明
add 將數組中對應的元素相加
subtract 從第一個數組中減去第二個數組中的元素
multiply 數組元素相乘
divide、floor_divide 除法或向下圓整除法(丟棄餘數)
power 對第一個數組中的元素A,根據第二個數組中的相應元素B,計算A^{B}
maximum、fmax 元素級的最大值計算。fmax將忽略NaN
minimum、fmin 元素級的最小值計算。fmin將忽略NaN
mod 元素級的求模計算(除法的餘數)
copysign 將第二個數組的元素符號賦給第一個數組的值
greater、greater_equal、less、less_equal、equal、not_equal 執行元素級的比較運算,最終產生布爾型數組。相當於中綴運算符>、>=、<、<=、==、!=
logical_and、logical_or、logical_xor 執行元素級的針織邏輯運算。相當於中綴運算符&、|、^

這些函數可以接受一個out可選參數,可以讓數組原地進行操作。需要注意的是out必須是已經存在的ndarray對象並且與返回結果的維度和dtype都相同。

In [181]: d                                                                                        
Out[181]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

In [182]: d1                                                                                       
Out[182]: 
array([[1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1]])

In [183]: np.add(d,d1,d1)                                                                          
Out[183]: 
array([[ 1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12]])

In [184]: d1                                                                                       
Out[184]: 
array([[ 1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12]])

利用數組進行數據處理:

In [212]: points=np.arange(-5,5,0.01)                                                              

In [213]: xs,ys=np.meshgrid(points,points)                                                         

In [214]: z=np.sqrt(xs**2+ys**2)                                                                   

In [215]: from matplotlib import pyplot as plt                                                     

In [216]: plt.imshow(z,cmap=plt.cm.gray);plt.colorbar()                                            
Out[216]: <matplotlib.colorbar.Colorbar at 0x7f7b70466eb8>

 np.meshgrid函數接受兩個一維數組,併產生兩個二維矩陣(對應於兩個數組中所有的(x,y)對),使用matplotlib 的imshow函數創建出下圖。

將條件邏輯表述爲數組運算:

In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])

In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])

In [167]: cond = np.array([True, False, True, True, False])

假設我們想要根據cond中的值選取xarr和yarr的值:當cond中的值爲True時,選取xarr的值,否則從yarr中選取。

In [170]: result = np.where(cond, xarr, yarr)

In [171]: result
Out[171]: array([ 1.1,  2.2,  1.3,  1.4,  2.5])

再舉一個例子,如果有兩個布爾型數組cond1和cond2,希望根據4中不同布爾值組合實現不同的賦值操作。

cond1 cond2 result
True True 0
True False 1
False True 2
False False 3

 可以這種方式實現

In [217]: np.where(cond1 & cond2,0,np.where(cond1,1,np.where(cond2,2,3)))

或者

In [219]: result=1*(cond1&-cond2)+2*(cond2&-cond1)+3*-(cond1|cond2) 

數學和統計方法:

基本數組統計方法

方法 說明
sum 對數組中全部或某軸向的元素求和。零長度的數組的sum爲0
mean 算術平均數。零長度的數組的mean爲NaN
std、var 分別爲標準差和方差,自由度可調(默認爲n)
min、max 最大值和最小值
argmax、argmin 分別爲最大和最小元素的索引
cumsum 所有元素的累計和
cumprod 所有元素的累計積

用於布爾型數組的方法:

方法 說明
any 檢查數組中是否存在一個或多個True
all 檢查數組中是否全是True

排序:

ndarray對象的sort是原地排序,多維數組可以在任何一個軸向上進行排序,只需將軸編號傳給sort即可,np.sort返回的是數組的已排序副本。

ndarray的基本集合運算:

方法 說明
unique(x) 計算x中的唯一元素,並返回有序結果
intersect1d(x,y) 計算x和y中的公共元素,並返回有序結果
union1d(x,y) 計算x和y的並集,並返回有序結果
in1d(x,y) 得到一個表示“x的元素是否包含於y”的布爾型數組
setdiff1d(x,y) 集合的差,即元素在x中且不在y中
setxor1d(x,y) 集合的對稱差,即存在於一個數組中但不同時存在於兩個數組中的元素

用於數組的文件輸入輸出:

方法 說明
save(path,ndarray) 將數組ndarray以原始二進制格式保存在路徑爲path的文件裏,文件擴展名爲.npy
load(path) 從路徑爲path的.npy文件中讀取ndarray數組或者從路徑爲path的.npz文件中讀取一個類似字典的對象,該對象將對各個數組延遲加載
savez(path,a=array1,b=array2,...) 將多個數組保存到一個未壓縮文件中,需要將多個數組以關鍵字參數形式傳入
savez_compressed(path,a=array1,b=array2,...) 與savez類似,但是這個方法會把數據壓縮後保存到文件中

線性代數:

NumPy提供了一個用於矩陣乘法的dot函數,即是ndarray對象的方法又是Numpy命名空間裏的一個函數。兩個ndarray對象可以使用中綴運算符@進行矩陣乘法運算。

In [3]: a                                                                         
Out[3]: 
array([[0, 1, 2],
       [3, 4, 5]])

In [4]: a @ a.T                                                                   
Out[4]: 
array([[ 5, 14],
       [14, 50]])

常用的numpy.linalg函數

方法 說明
diag 以一維數組的形式返回方陣的對角線(或非對角線)元素,或將一維數組轉換爲方陣(非對角線元素爲0)
dot 矩陣乘法
trace 計算對角線元素的和
det 計算矩陣行列式
eig 計算方陣的本徵值和本徵向量
inv 計算方陣的逆
prinv 計算矩陣的Moore-Penrose僞逆
qr 計算QR分解
svd 計算奇異值分解(SVD)
solve 解線性方程Ax=b,其中A爲一個方陣
lstsq 計算Ax=b的最小二乘解

僞隨機數生成:

部分numpy.random函數

方法 說明
seed 確定隨機數生成器的種子
permutation 返回一個序列的隨機排列或返回一個隨機排列的範圍
shuffle 對一個序列就地隨機排列
rand 產生均勻分佈的樣本值
randint 從給定的上下限範圍內隨機選取整數
randn 產生正態分佈(平均值爲0,標準差爲1)的樣本值,類似於MATLAB接口
binomial 產生二項分佈的樣本值
normal 產生正態(高斯)分佈的樣本值
beta 產生Beta分佈的樣本值
chisquare 產生卡方分佈的樣本值
gamma 產生Gamma分佈的樣本值
uniform 產生在[0,1)中均勻分佈的樣本值

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章