什么是NumPy?

2021-11-06 17:33 更新

NumPyPython 科學(xué)計算的基礎(chǔ)包。它是一個 Python 庫,提供了一個多維數(shù)組對象、各種派生對象(例如掩碼數(shù)組和矩陣),以及用于對數(shù)組進(jìn)行快速操作的各種例程,包括數(shù)學(xué)、邏輯形狀操作、排序選擇、I/O 、離散傅立葉變換基本線性代數(shù)、基本統(tǒng)計運(yùn)算、隨機(jī)模擬等等。

NumPy 包的核心是 ndarray 對象。其封裝了同構(gòu)數(shù)據(jù)類型的 n維數(shù)組,許多操作在編譯代碼中執(zhí)行以提高性能。NumPy 數(shù)組和標(biāo)準(zhǔn) Python 序列之間有幾個重要的區(qū)別:

  • 與 Python 列表(可以動態(tài)增長)不同,NumPy 數(shù)組在創(chuàng)建時具有固定大小。更改ndarray的大小將創(chuàng)建一個新數(shù)組并刪除原始數(shù)組。
  • NumPy 數(shù)組中的元素都需要具有相同的數(shù)據(jù)類型,因此在內(nèi)存中的大小相同。例外:可以有(Python,包括 NumPy)對象的數(shù)組,從而允許不同大小元素的數(shù)組。
  • NumPy 數(shù)組有助于對大量數(shù)據(jù)進(jìn)行高級數(shù)學(xué)運(yùn)算和其他類型的運(yùn)算。通常,與使用 Python 的內(nèi)置序列相比,此類操作的執(zhí)行效率更高,代碼更少。
  • 越來越多的基于 Python 的科學(xué)和數(shù)學(xué)包正在使用 NumPy 數(shù)組;盡管這些通常支持 Python 序列輸入,但它們在處理之前將此類輸入轉(zhuǎn)換為 NumPy 數(shù)組,并且通常輸出 NumPy 數(shù)組。換句話說,為了有效地使用大部分基于 Python 的科學(xué)/數(shù)學(xué)軟件,僅僅知道如何使用 Python 的內(nèi)置序列類型是不夠的——還需要知道如何使用 NumPy 數(shù)組。

關(guān)于序列大小和速度的要點在科學(xué)計算中尤為重要。作為一個簡單的例子,考慮將一維序列中的每個元素與另一個相同長度序列中的相應(yīng)元素相乘的情況。如果數(shù)據(jù)存儲在兩個 Python 列表a和 中b,我們可以遍歷每個元素:

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

得出了正確的答案,但如果ab每一個都包含數(shù)以百萬計的數(shù)字,我們會因為 Python 中循環(huán)的的低效率而付出代價。我們可以在 C 中通過編寫代碼更快地完成相同的任務(wù)(為清楚起見,我們忽略了變量聲明和初始化、內(nèi)存分配等):

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

節(jié)省了解釋 Python 代碼和操作 Python 對象所涉及的所有開銷,但代價是犧牲了使用 Python 編碼所帶來的好處。此外,所需的編碼工作隨著數(shù)據(jù)維度的增加而增加。例如,在二維數(shù)組的情況下,C 代碼(如前所述縮寫)擴(kuò)展為:

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

NumPy 為我們提供了兩全其美的方法:當(dāng)涉及 ndarray 時,逐元素操作是“默認(rèn)模式”,但逐元素操作由預(yù)編譯的 C 代碼快速執(zhí)行。 在 NumPy 中:

c = a * b

以接近 C 的速度執(zhí)行前面的示例所做的事情,而且代碼的簡單性又符合我們希望和 Python 一樣。事實上,NumPy 習(xí)慣用法更簡單!最后一個示例說明了 NumPy 的兩個功能,這兩個功能是其大部分強(qiáng)大功能的基礎(chǔ):矢量化廣播

為什么NumPy更快?

矢量化描述了代碼中沒有任何顯式循環(huán)、索引等。當(dāng)然,這些事情只是在優(yōu)化、預(yù)編譯 C 代碼的“幕后”發(fā)生的。矢量化代碼有很多優(yōu)點,其中包括:

  • 矢量化代碼更簡潔易讀
  • 更少的代碼通常意味著更少的錯誤
  • 代碼更接近標(biāo)準(zhǔn)數(shù)學(xué)符號(通常更容易正確編碼數(shù)學(xué)結(jié)構(gòu))
  • 矢量化會產(chǎn)生更多的Pythonic代碼。如果沒有矢量化,我們的代碼將充斥著低效且難以閱讀的for循環(huán)。

廣播是用于描述操作的隱式逐元素行為的術(shù)語;一般而言,在 NumPy 中,所有操作,不僅是算術(shù)運(yùn)算,還有邏輯、按位、函數(shù)等,都以這種隱式的逐元素方式表現(xiàn),即它們正在廣播。此外,在上面的例子中,ab可以是相同形狀的多維數(shù)組,或者一個標(biāo)量和一個數(shù)組,甚至兩個不同形狀的數(shù)組,前提是較小的數(shù)組可以“擴(kuò)展”到較大的數(shù)組中,由此產(chǎn)生的廣播是明確的。

還有誰在使用NumPy?

NumPy 完全支持面向?qū)ο蟮姆椒?,再次?ndarray 開始。例如,ndarray是一個類,擁有許多方法和屬性。它的許多方法由最外層 NumPy 命名空間中的函數(shù)鏡像,允許程序員以他們喜歡的任何樣式進(jìn)行編碼。這種靈活性使 NumPy 數(shù)組方言和 NumPy?ndarray 類成為 Python 中使用的多維數(shù)據(jù)交換的事實上的語言。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號