NumPyPython语言的一个扩展程序库。支持高阶大规模的多维数组矩阵运算,此外也针对数组运算提供大量的数学函数函数库。NumPy的前身Numeric最早是由Jim Hugunin与其它协作者共同开发,2005年,Travis Oliphant在Numeric中结合了另一个同性质的程序库Numarray的特色,并加入了其它扩展而开发了NumPy。NumPy为开放源代码并且由许多协作者共同维护开发。

NumPy
原作者特拉维斯·奥利芬特英语Travis Oliphant
开发者社群项目
首次发布Numeric, 1995年 (1995);
NumPy, 2006年 (2006)
当前版本2.2.1[1]在维基数据编辑(2024年12月21日,4天前)
源代码库 编辑维基数据链接
编程语言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]

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.2.1. 2024年12月21日 [2024年12月25日]. 
  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) (英语). 

扩展阅读

编辑

外部链接

编辑