Numpy複習總結(一)

本篇文章將總結Numpy的基礎知識,標題如下

  1. Numpy簡介
  2. ndarray
  3. ndarray數據類型
  4. 修改ndarray的形狀
  5. ndarray索引和切片
  6. ndarray的轉置與軸變換
  7. 通用函數
  8. ndarray與標量的運算
  9. ndarray的「三目運算符」

Numpy簡介

NumPy是用Python進行科學計算的基本軟體包。它包含以下內容:

  • 一個強大的N維數組對象
  • 複雜的(廣播)功能
  • 用於集成C / C ++和Fortran代碼的工具
  • 有用的線性代數,傅里葉變換和隨機數能力
  • 用於讀寫磁碟數據以及操作內存映射文件的工具

NumPy的優勢在於NumPy底層使用C語言編寫,其對數組的操作速度不受Python解釋器的限制,效率遠高於純Python代碼。並且結合Python腳本語言的特點,使得代碼比起其他語言更簡潔易讀。除了明顯的科學用途外,NumPy還可以用作通用數據的高效多維容器。任意的數據類型可以被定義。這使得NumPy能夠與各種各樣的資料庫無縫,快速地整合。

ndarray

ndarray是一個N維齊次同構數組對象,每個數組都有一個shapedtype屬性,shape描述的是ndarray的形狀,而dtype則描述ndarray裡面元素的數據類型。

創建ndarray

通常創建ndarray會用如下幾種方法

下面是創建ndarray的例子

可以看到numpy根據輸入的嵌套列表,生成了一個二維數組,每一維有三個元素,而且我們可以看到該數組元素的數據類型均為int64(因為沒有顯式的指定dtype參數,所以numpy自己推斷了int64這個數據類型,int64為64位整型)

ndarray數據類型

dtype含有將ndarray解釋為特定數據類型的所需的信息,數據的類型命名有規律,均為類型名+位寬(一個位元組有8個位寬)如上面例子中的int64。dytpe有整型、浮點數、字元串、複數、布爾值、Python對象等等。

如果你沒有在創建ndarray數組時顯式的指明dtype,你仍可以通過astype(type)方法修改數據類型為type,但是使用astype會返回一個新的數組,浪費額外的內存,因此建議在創建ndarray數組的時候指定數據對象。(注意浮點數轉化為整型數會把小數部分截斷)

修改ndarray的形狀

shape屬性描述了ndarray數組的形狀ndarray.shape會返回描述形狀而元祖,元祖內元素的個數表示數組有多少個維度,元素的值描述了某個維度的長度。在創建ndarray數組的時候我們可以用一個元祖指定shape參數的取值來控制數組的形狀。或者在創建數組之後,直接對數組的shape屬性賦值或者使用reshape()方法來返回一個指定形狀的新數組。

在使用reshape的時候若你指定傳入-1為參數,那麼返回的數組將會是1維,

當你指定了n-1維的值後,剩下一維的大小可以傳入-1,由numpy自己計算出該維度的大小

reshape()方法雖然可以改變數組的形狀,但由於數組元素的個數是恆定不變的,而且顯然數組元素個數為各個維度大小的乘積。但在有些時候,我們需要給數組添加一些新的元素。numpy中有column_stack()row_stack()方法,可以把兩個數組合併,達到增加元素的效果。

column_stack()為例,該函數接受一個元祖作為參數將元祖內的數組按列堆疊,上例將形狀為(2,1)的數組堆疊到array,顯然按列堆疊必須要行數必須相等。大於二維的數組若想要成功按列堆疊,則需要除列以外所有維度的大小相等。

類似的函數或類還有concatenate()、vstack()、r_、c_等等,其中concatenate()為最一般的連接方法,它可以指定按某一個軸進行數組的合併。

除了合併,還可以用split()函數傳入指定軸以及切分點的索引值拆分數組(傳入n個切分索引則返回n+1個數組),類似的方法還有hsplit() 、vsplit() 、dsplit()有興趣的朋友可以去查看官方文檔。

ndarray索引和切片

Python列表的索引和切片操作在ndarray上仍然適用。但是要注意ndarray的切片返回的是數組的視圖而非副本,如果你想要獲得副本,這需要顯式的調用copy()方法

以上代碼可以選取除最後一列的其他元素,可以看到在numpy里,所有維度的索引可以寫在一個中括弧內,並且用逗號隔開(分別寫在多個中括弧也是可以的,這種寫法和Python列表索引的寫法相同)。

ndarray還有著特殊的索引方式,分布是布爾型索引花式索引。

布爾型索引就是在中括弧內放入布爾型數組,數組會根據布爾型數組的真值來選擇數據。

上例中在索引里加入布爾表達式,可以生成與原數組形狀相同的布爾型數組,如上圖所示array>3返回的是是一個與原數組形狀相同的布爾型數組。原數組對應位置的元素的值為該元素對於給定布爾表達式的真值。因此只有4,5,6對應的位置應位置的取值才為True。若把布爾型數組放入索引,就可以按照布爾數組來索引元素了。(注意布爾型數組的長度必須與被索引軸的長度相等)

花式索引就是把一個指定順序的整數順序的列表或者ndarray數組放入中括弧內,就可以按照特定順序選取子集例如我想選第0列和第2列的全部元素,那麼就可以向下面那樣進行索引。

或者我想先選取第2列再選取第0列,只須修改列表裡元素的順序即可。

numpy索引的方法有很多,但是各種索引方式之間的效率和空間是不一樣的。例如我們現在有一個比較大的數組,我們打算每隔10個行選取1行,則可以有以下兩種方式。

可以看到使用切片會比花式數組快兩個數量級,這是因為切片返回的是原數組的視圖,修改視圖會修改原數組。但是花式索引返回的是卻是一個新的數組。實際上使用切片再顯式的拷貝也比使用花式數組要快。故等步長選取數據時優先使用切片會有更好的性能。

但你選取的數據不是按等步長的選擇時,可以使用np.take()方法,他接受一個數組,索引數組以及軸作為參數,如下例所示

使用take()方法可以比使用花式索引快那麼一點點。在使用布爾型索引按某一軸的時候,使用np.compress()的效率會更高。(np.compress()用法和take一樣)。

ndarray的轉置與軸變換

若想實現數組的轉置可以使用transpose()方法接受描述軸順序的元祖作為參數,並根據這一元祖對元素重新排序。例如一個二維數組的軸原來為(0,1),當你改變軸的順序為

(1,0)即可實現轉置。

也可以直接使用.T簡單轉置

在處理二維數組的時候使用.T.transpose()並沒有差異,但是.transpose()可以實現更複雜的軸變換,而.T值能實現軸的按逆序來進行軸變換。(注意一維數組的轉置為本身)

通用函數

通用函數是一種對ndarray中的數據進行元素級運算的函數。這些函數非常好上手,都是一些看到名字就知道作用的函數,例如absfbs、sqrt

、exp等等。numpy的數學函數庫非常的豐富,在此就不一一說明,以下是例子。

可以看到每一個元素都被開平方。

ndarray與標量之間運算

ndarray支持數組直接用運算符來與標量運算。運算的效果為數組的每一個元素都與標量進行運算,這一點符合和我們正常的使用習慣。並且對於形狀相同的兩個數組,使用運算符直接運算,會轉化為對應位置元素之間的運算,一下是例子。

可以看到原數組的每一個元素的值都加1了。

ndarray的「三目運算符」

在numpy中有一個where函數,常用於對特定數據進行修改或者選取。其用法有點像C語言中的三目運算符。

where()函數接受三個參數,第一個是邏輯表達式,若邏輯表達式為真則選取第二個參數,否則選取第三個參數。第二個和第三個參數可以是標量也可以是數組。本質上就是一個if...else...語句快。

如上例所示,但arr1arr2對應位置的元素進行比較,若arr1中對應位置的元素大於arr2對應位置的元素,則選取arr1中的元素,否則選取arr2中的元素。故結果為 array( [ 3,2,3] )

本期為大家簡單介紹了numpy的部分內容,下期Python基礎將會更深入地為大家介紹numpy的使用方法。

本文首發於公眾號「AI遇見機器學習」,更多乾貨可搜索[mltoai]或直接公眾號名,歡迎關注!

推薦閱讀:

《StackGAN: Text to Photo-realistic Image Synthesis with Stacked GAN》閱讀筆記
關於Kaggle的一些數據分析
自動生成硬體優化內核:陳天奇等人發布深度學習編譯器TVM
機器學習之Logistic回歸(五)
Deep Reinforcement Learning for Dialogue Generation

TAG:Python | numpy | 机器学习 |