numpy概念(一)

baidu_252253發表於2019-02-26

NumPy是Python中科學計算的基礎包。它是一個Python庫,提供多維陣列物件,各種派生物件(如掩碼陣列和矩陣),以及用於陣列快速操作的各種例程,包括數學,邏輯,形狀操作,排序,選擇,I / O離散傅立葉變換,基本線性代數,基本統計運算,隨機模擬等等。

NumPy 是 Python 的一個外部模組,它提供了一個多維陣列(ndarray)資料型別,以及關於多維陣列的操作,NumPy 已經成為其他大資料和機器學習模組的基礎。

NumPy包的核心是ndarray物件。這封裝了同構資料型別的n維陣列,許多操作在編譯程式碼中執行以提高效能。NumPy陣列和標準Python序列之間有幾個重要的區別:

  • NumPy陣列在建立時具有固定大小,與Python列表(可以動態增長)不同。更改ndarray的大小將建立一個新陣列並刪除原始陣列。
  • NumPy陣列中的元素都需要具有相同的資料型別,因此在記憶體中的大小相同。例外:可以有(Python,包括NumPy)物件的陣列,從而允許不同大小的元素的陣列。
  • NumPy陣列有助於對大量資料進行高階數學和其他型別的操作。通常,與使用Python的內建序列相比,這些操作的執行效率更高,程式碼更少。
  • 越來越多的基於Python的科學和數學軟體包正在使用NumPy陣列; 雖然這些通常支援Python序列輸入,但它們在處理之前將這些輸入轉換為NumPy陣列,並且它們通常輸出NumPy陣列。換句話說,為了有效地使用當今大量(甚至大多數)基於Python的科學/數學軟體,只知道如何使用Python的內建序列型別是不夠的 - 還需要知道如何使用NumPy陣列。

關於序列大小和速度的要點在科學計算中尤為重要。作為一個簡單的例子,考慮將1-D序列中的每個元素與相同長度的另一個序列中的相應元素相乘的情況。如果資料被儲存在兩個Python列表,a並且b,我們可以遍歷每個元素:

c = []
for i in range(len(a)):
    c.append(a[i]*b[i])

這產生了正確的答案,但如果ab每個包含數百萬個數字,我們將為Python中迴圈的低效率付出代價。我們可以通過寫入在C中更快地完成相同的任務(為了清楚起見,我們忽略了變數宣告和初始化,記憶體分配等)

for  (i  =  0 ;  i  <  rows ;  i ++ ): { 
  c [ i ]  =  a [ i ] * b [ i ]; 
}

這節省了解釋Python程式碼和操作Python物件所涉及的所有開銷,但代價是從Python編碼中獲得的好處。此外,所需的編碼工作隨著我們資料的維度而增加。例如,在二維陣列的情況下,C程式碼(如前所述)擴充套件為

for (i = 0; i < rows; i++): {
  for (j = 0; j < columns; j++): {
    c[i][j] = a[i][j]*b[i][j];
  }
}

NumPy為我們提供了兩全其美:當涉及到ndarray時,逐個元素的操作是“預設模式” ,但逐個元素的操作由預編譯的C程式碼快速執行。在NumPy

c  =  a  *  b

以近C速度執行前面的示例所做的事情,但是我們期望基於Python的程式碼具有簡單性。的確,NumPy成語更簡單!最後一個例子說明了NumPy的兩個特徵,它們是它的大部分功能的基礎:向量化和廣播。

Vectorization描述了程式碼中沒有任何顯式迴圈,索引等 - 這些事情當然只是在優化的,預編譯的C程式碼中“幕後”。向量化程式碼有許多優點,其中包括:

  • 向量化程式碼更簡潔,更易於閱讀
  • 更少的程式碼行通常意味著更少的錯誤
  • 程式碼更接近於標準的數學符號(通常,更容易,正確編碼數學結構)
  • 向量化導致更多“Pythonic”程式碼。如果沒有向量化,我們的程式碼就會被低效且難以閱讀的for迴圈所困擾。

廣播是用於描述操作的隱式逐元素行為的術語; 一般來說,在NumPy中,所有操作,不僅僅是算術運算,而是邏輯,位,功能等,都以這種隱式的逐元素方式表現,即它們進行廣播。此外,在上面的例子中,a並且b可以是相同形狀的多維陣列,或者標量和陣列,或者甚至是具有不同形狀的兩個陣列,條件是較小的陣列可以“擴充套件”到更大的形狀。結果廣播明確無誤的方式。有關廣播的詳細“規則”,請參閱numpy.doc.broadcasting

NumPy完全支援物件導向的方法,再次使用ndarray開始。例如,ndarray是一個類,擁有許多方法和屬性。它的許多方法都在最外層的NumPy名稱空間中映象函式,使程式設計師可以完全自由地編寫她喜歡的範例和/或最適合手頭任務的範例。