Home >> Blog >> python numpy - 什麼是 numpy?
python numpy - 什麼是 numpy?
NumPy 是 Python 中科學計算的基礎包。它是一個 Python 庫,提供多維數組對象、各種派生對象(例如掩碼數組和矩陣)以及用於對數組進行快速操作的各種例程,包括數學、邏輯、形狀操作、排序、選擇、I/O 、離散傅里葉變換、基本線性代數、基本統計運算、隨機模擬等等。
NumPy 包的核心是ndarray對象。這封裝了同質資料類型的n維數組,許多操作在編譯程式碼中執行以提高性能。NumPy 數組和標準 Python 序列之間有幾個重要的區別:
- NumPy 數組在創建時具有固定大小,這與 Python 列表(可以動態增長)不同。更改ndarray的大小將創建一個新數組並刪除原始數組。
- NumPy 數組中的元素都必須具有相同的資料類型,因此在內存中的大小相同。例外:可以有(Python,包括 NumPy)對象的數組,從而允許不同大小元素的數組。
- NumPy 數組有助於對大量資料進行高級數學運算和其他類型的運算。通常,與使用 Python 的內置序列相比,此類操作的執行效率更高,程式碼更少。
- 越來越多的基於 Python 的科學和數學軟件包正在使用 NumPy 數組;儘管這些通常支持 Python 序列輸入,但它們會在處理之前將此類輸入轉換為 NumPy 數組,並且它們通常會輸出 NumPy 數組。換句話說,為了有效地使用當今許多(甚至大部分)基於 Python 的科學/數學軟件,僅僅知道如何使用 Python 的內置序列類型是不夠的——還需要知道如何使用 NumPy 數組。
關於序列大小和速度的要點在科學計算中尤為重要。作為一個簡單的例子,考慮將一維序列中的每個元素與另一個相同長度序列中的對應元素相乘的情況。如果資料存儲在兩個 Python 列表a和b中,我們可以遍歷每個元素:
c = []
for i in range(len(a)):
c.append(a[i]*b[i])
這會產生正確的答案,但如果a每個b都包含數百萬個數字,我們將為 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 的兩個功能,它們是其強大功能的基礎:矢量化和廣播。
為什麼 NumPy 快?
矢量化描述了程式碼中沒有任何顯式循環、索引等 - 當然,這些事情只是在優化的、預編譯的 C 程式碼中“在幕後”發生。矢量化程式碼有很多優點,其中包括:
- 矢量化程式碼更簡潔,更易於閱讀
- 更少的程式碼行通常意味著更少的錯誤
- 程式碼更接近標準數學符號(通常更容易正確編寫程式數學結構)
- 矢量化導致更多“Pythonic”程式碼。如果沒有矢量化,我們的程式碼將充滿低效且難以閱讀的for循環。
廣播是用於描述操作的隱式逐個元素行為的術語;一般來說,在 NumPy 中,所有操作,不僅是算術運算,而且是邏輯、位、函數等,都以這種隱式的逐元素方式表現,即它們廣播。此外,在上面的示例中,a並且b可以是相同形狀的多維數組,也可以是一個標量和一個數組,甚至可以是兩個不同形狀的數組,前提是較小的數組可以“擴展”為較大的數組。一種結果廣播是明確的方式。有關廣播的詳細“規則”。
還有誰使用 NumPy?
NumPy 完全支持面向對象的方法,再次從ndarray 開始。例如,ndarray是一個類,擁有許多方法和屬性。它的許多方法都由最外層 NumPy 命名空間中的函數鏡像,允許程式設計師以他們喜歡的任何範例進行編寫程式。這種靈活性使得 NumPy 數組方言和 NumPy ndarray類成為Python 中使用的多維資料交換的事實語言。