NumPyPython語言的一個擴充程式庫。支援高階大規模的多維陣列矩陣運算,此外也針對陣列運算提供大量的數學函數函式庫。NumPy的前身Numeric最早是由Jim Hugunin與其它協作者共同開發,2005年,Travis Oliphant在Numeric中結合了另一個同性質的程式庫Numarray的特色,並加入了其它擴充功能而開發了NumPy。NumPy為開放原始碼並且由許多協作者共同維護開發。

NumPy
原作者特拉維斯·奧利芬特英語Travis Oliphant
開發者社群專案
首次釋出Numeric, 1995年 (1995);
NumPy, 2006年 (2006)
目前版本2.1.3[1]在維基數據編輯(2024年11月2日,26天前)
原始碼庫 編輯維基數據連結
程式語言Python, C語言
作業系統跨平台
類型數值分析
特許條款BSD特許條款
網站www.numpy.org

歷史

Matrix-sig

儘管很早就受到了科學界和工業界的關注,但Python最初並不是為數值計算設計的。1995年,特殊興趣小組(Special Interest Group,SIG)Matrix-sig成立,其目的是設計一個陣列計算包。Matrix-sig的成員中有Python的設計者和維護者吉多·范羅蘇姆,他擴充了Python的語法(特別是索引語法[2]),使陣列計算更容易。[3]

Numeric

矩陣包Numeric由Jim Fulton實現,並由Jim Hugunin推廣[3], (也稱Numerical Python extensions或 NumPy)。[4][5]Jim Hugunin 是麻省理工學院的研究生,[5]:10 於1997年加入國家研究計劃公司英語Corporation_for_National_Research_Initiatives從事JPython的研發[3]勞倫斯利弗莫爾國家實驗室的Paul Dubois接任維護者。[5]:10其他早期貢獻者包括David Ascher, Konrad Hinsen和Travis Oliphant。[5]:10

Numarray

Numarray是作為Numeric的替代品被開發出來的[6],現已廢棄。[7][8]相比於Numeric,Numarray處理大陣列速度較快,然而處理小陣列速度較慢,[9]因此有一段時間這兩個包被並列使用於不同情況。Numeric的最後一個版本(v24.2)於2005年11月11日釋出;Numarray的最後一個版本(v1.5.2)於2006年8月24日釋出。[10]

有人希望將Numeric納入Python標準庫,但吉多·范羅蘇姆認為,在當時的情況下,代碼難以維護。[11]

NumPy

2005年初,NumPy的開發者Travis Oliphant希望社區的不同陣列包可以統一。他將Numarray的功能移植到Numeric上,並於2006將結果作為NumPy 1.0釋出。[6]這個新專案是SciPy的一部分。為了避免在只需陣列計算的情況下安裝龐大的SciPy包,新包以NumPy的名義被分離出來。2011年,NumPy的1.5.0版本加入了對Python 3的支援。[12]

2011年,PyPy開始開發NumPy API,[13]但它尚未與NumPy完全相容。[14]

特色

NumPy參考CPython(一個使用位元組碼直譯器),而在這個Python實作直譯器上所寫的數學演算法程式碼通常遠比編譯過的相同程式碼要來得慢。為了解決這個難題,NumPy引入了多維陣列以及可以直接有效率地操作多維陣列的函數與運算子。因此在NumPy上只要能被表示為針對陣列或矩陣運算的演算法,其執行效率幾乎都可以與編譯過的等效C語言程式碼一樣快[15]

NumPy提供了與MATLAB相似的功能與操作方式,因為兩者皆為直譯語言,並且都可以讓用戶在針對陣列或矩陣運算時提供較純量運算更快的效能。兩者相較之下,MATLAB提供了大量的擴充工具箱(例如Simulink);而NumPy則是根基於Python這個更現代、完整並且開放原始碼的程式語言之上。此外NumPy也可以結合其它的Python擴充函式庫。例如SciPy,這個函式庫提供了更多與MATLAB相似的功能;以及Matplotlib,這是一個與MATLAB內建繪圖功能類似的函式庫。而從本質上來說,NumPy與MATLAB同樣是利用BLASLAPACK來提供高效率的線性代數運算。

ndarray 數據結構

NumPy的核心功能是ndarray(即n-dimensional array,多維陣列)數據結構。這是一個表示多維度、同質並且固定大小的陣列物件。而由一個與此陣列相關聯的資料型態物件來描述其陣列元素的資料格式(例如其字元組順序、在記憶體中佔用的字元組數量、整數或者浮點數等等)。

局限性

在陣列中插入或追加元素並不像Python的list一樣簡單。np.pad(...)實際上建立了新的具有目標形狀和填充值的陣列,將給定陣列的值複製到新陣列中並返回新陣列。np.concatenate([a1,a2])並沒有直接連接兩個陣列,而是返回新的陣列,該陣列填充了兩個原陣列的值。用np.reshape(...)改變陣列的維度只有在陣列中元素數量不變的情況下才能實現。造成以上情況的原因是NumPy的陣列必須佔用連續的主記憶體空間。Blaze包嘗試克服這個限制。[16]

未經向量化的演算法通常執行緩慢,因為它們必須用純Python方法實現;由於需要建立和輸入等大的臨時陣列,部分操作的向量化可能會增長其空間複雜度(例如由常數增長到線性)。部分小組通過執行時編譯(Runtime compilation of numerical code)避免這一問題。可與NumPy整合的開源解決方案包括 numexpr[17]Numba[18]。Cython和Pythran是靜態編譯的解決方案。

許多現代大型科學計算應用的要求超出了NumPy陣列的能力。例如,NumPy陣列通常載入到電腦的主記憶體中,然而主記憶體可能沒有足夠的容量;此外,NumPy僅在單個CPU上進行操作,而許多線性代數算子可以通過CPU的叢集和其它特殊硬件(例如GPUTPU,部分深度學習應用也依賴於這些特殊硬件)來加速。因此,近期在Python的生態中出現了許多其它工具,例如用於分散式陣列的Dask英語Dask、用於GPU計算的TensorFlowJAX等。這些庫通常實現或模仿NumPy的部分API,因此用戶不需大量改動就可以部署原先使用NumPy的程式。[19]近期出現的由Nvidia的CUDA架構加速的CuPy英語CuPy[20]展示了快速計算的潛力,是NumPy的直接替代品。[21]

語法

格點
>>> import numpy as np
>>> x = np.array([1, 2, 3])
>>> x
array([1, 2, 3])
>>> y = np.arange(10)  # 類似 Python 的 range, 但是回傳 array
>>> y
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
基本運算
>>> a = np.array([1, 2, 3, 6])
>>> b = np.linspace(0, 2, 4)  # 建立一個array, 在0與2的範圍之間讓4個點3等分
>>> c = a - b
>>> c
array([ 1.        ,  1.33333333,  1.66666667,  4.        ])
>>> a**2
array([ 1,  4,  9, 36])
全域方法
>>> a = np.linspace(-np.pi, np.pi, 100) 
>>> b = np.sin(a)
>>> c = np.cos(a)
線性代數
>>> from numpy.random import rand
>>> from numpy.linalg import solve, inv
>>> a = np.array([[1, 2, 3], [3, 4, 6.7], [5, 9.0, 5]])
>>> a.transpose()
array([[ 1. ,  3. ,  5. ],
       [ 2. ,  4. ,  9. ],
       [ 3. ,  6.7,  5. ]])
>>> inv(a)
array([[-2.27683616,  0.96045198,  0.07909605],
       [ 1.04519774, -0.56497175,  0.1299435 ],
       [ 0.39548023,  0.05649718, -0.11299435]])
>>> b =  np.array([3, 2, 1])
>>> solve(a, b)  # 解方程式 ax = b
array([-4.83050847,  2.13559322,  1.18644068])
>>> c = rand(3, 3)  # 建立一個 3x3 隨機矩陣
>>> c
array([[  3.98732789,   2.47702609,   4.71167924],
       [  9.24410671,   5.5240412 ,  10.6468792 ],
       [ 10.38136661,   8.44968437,  15.17639591]])
>>> np.dot(a, c)  # 矩陣相乘
array([[  53.61964114,   38.8741616 ,   71.53462537],
       [ 118.4935668 ,   86.14012835,  158.40440712],
       [ 155.04043289,  104.3499231 ,  195.26228855]])

參考資料

  1. ^ 1.0 1.1 Release 2.1.3. 2024年11月2日 [2024年11月9日]. 
  2. ^ Indexing — NumPy v1.20 Manual. numpy.org. [2021-04-06]. (原始內容存檔於2023-06-12). 
  3. ^ 3.0 3.1 3.2 Millman, K. Jarrod; Aivazis, Michael. Python for Scientists and Engineers. Computing in Science and Engineering. 2011, 13 (2): 9–12 [2014-07-07]. Bibcode:2011CSE....13b...9M. doi:10.1109/MCSE.2011.36. (原始內容存檔於2019-02-19). 
  4. ^ Travis Oliphant. Python for Scientific Computing (PDF). Computing in Science and Engineering. 2007 [2013-10-12]. (原始內容 (PDF)存檔於2013-10-14). 
  5. ^ 5.0 5.1 5.2 5.3 David Ascher; Paul F. Dubois; Konrad Hinsen; Jim Hugunin; Travis Oliphant. Numerical Python (PDF). 1999 [2023-03-17]. (原始內容存檔 (PDF)於2023-03-17). 
  6. ^ 6.0 6.1 van der Walt, Stéfan; Colbert, S. Chris; Varoquaux, Gaël. The NumPy array: a structure for efficient numerical computation. Computing in Science and Engineering (IEEE). 2011, 13 (2): 22. Bibcode:2011CSE....13b..22V. S2CID 16907816. arXiv:1102.1523 . doi:10.1109/MCSE.2011.37. 
  7. ^ Numarray Homepage. [2006-06-24]. (原始內容存檔於2021-06-09). 
  8. ^ Travis E. Oliphant. Guide to NumPy. 7 December 2006 [2 February 2017]. 
  9. ^ Travis Oliphant and other SciPy developers. [Numpy-discussion] Status of Numeric. [2 February 2017]. (原始內容存檔於2017-02-03). 
  10. ^ NumPy Sourceforge Files. [2008-03-24]. (原始內容存檔於2012-03-02). 
  11. ^ History_of_SciPy - SciPy wiki dump. scipy.github.io. [2023-03-17]. (原始內容存檔於2023-03-17). 
  12. ^ NumPy 1.5.0 Release Notes. [2011-04-29]. (原始內容存檔於2021-12-09). 
  13. ^ PyPy Status Blog: NumPy funding and status update. [2011-12-22]. (原始內容存檔於2023-03-25). 
  14. ^ NumPyPy Status. [2013-10-14]. (原始內容存檔於2013-10-16). 
  15. ^ SciPy PerformancePython. [2006-06-25]. (原始內容存檔於2015-01-13). 
  16. ^ Blaze Ecosystem Docs. Read the Docs. [17 July 2016]. [失效連結]
  17. ^ Francesc Alted. numexpr. GitHub. [8 March 2014]. (原始內容存檔於2023-03-24). 
  18. ^ Numba. [8 March 2014]. (原始內容存檔於2023-06-01). 
  19. ^ Charles R Harris; K. Jarrod Millman; Stéfan J. van der Walt; et al. Array programming with NumPy (PDF). 自然. 2020-09-16, 585 (7825): 357–362. ISSN 1476-4687. PMC 7759461 . PMID 32939066. arXiv:2006.10256 . doi:10.1038/S41586-020-2649-2. Wikidata Q99413970 (英語). 
  20. ^ Shohei Hido - CuPy: A NumPy-compatible Library for GPU - PyCon 2018, [2021-05-11], (原始內容存檔於2021-12-21) (英語) 
  21. ^ Entschev, Peter Andreas. Single-GPU CuPy Speedups. Medium. 2019-07-23 [2021-05-11]. (原始內容存檔於2023-03-16) (英語). 

擴充閱讀

外部連結