天天看点

牛!NumPy团队发了篇Nature

牛!NumPy团队发了篇Nature

0 首先要知道Numpy是啥文献摘要

  • 数组编程为访问和操作矢量、矩阵和高维数组中的数据提供了强大的语法。
  • NumPy是Python语言的主要数组编程库。它在物理、化学、天文学、地学、生物学、心理学、材料科学、工程、金融和经济等不同领域的研究分析中发挥着至关重要的作用。
  • NumPy是构建科学Python生态系统的基础。

在这里,我们回顾几个基本的数组概念,展示一个简单而强大的用于分析科学数据的编程范例。

牛!NumPy团队发了篇Nature

2 Numpy数组

2.1数据结构

牛!NumPy团队发了篇Nature

NumPy数组是有效存储和访问多维数组(张量)的数据结构,并且能够进行各种科学计算。它包括一个指向内存的指针,以及用于解释存储在那里的数据的元数据,特别是“data type”、“shape”和“strides”。

data type描述数组中存储的元素的性质。数组只有一种数据类型,并且数组的每个元素在内存中占用相同数量的字节。数据类型的示例包括real and complex numbers, strings, timestamps and pointers to Python objects.

shape决定了沿每个轴的元素数量,轴的数量就是数组的维度。例如,数字矢量可以存储为形状为N的一维数组,而彩色视频则是形状为(T,M,N,3)的四维数组。

Strides是将线性存储元素的计算机内存解释为多维数组所必需的,描述了在内存中向前移动的字节数,以便从行跳到行,从列跳到列等等。例如,考虑一个形状为(4,3)的二维浮点数组,其中每个元素在内存中占据8个字节。要在连续的列之间移动,我们需要在内存中向前跳转8个字节,要访问下一行,需要3×8=24个字节。因此该数组的步长为(24,8)。NumPy可以按C或Fortran内存顺序存储数组,先迭代行或列。这使得用这些语言编写的外部库可以直接访问内存中的NumPy数组数据。

2.2索引

用户使用“索引”(访问子数组或单个元素)、“运算符”以及“array-aware 函数”与NumPy数组交互;这些共同为数组编程提供了一个易于阅读、可表达的高级API,而NumPy则处理快速操作的底层机制。

牛!NumPy团队发了篇Nature

索引数组将返回满足特定条件的单个元素、子数组或元素(b)。

数组甚至可以使用其他数组进行索引(c)。只要有可能,检索子数组的索引就会返回原始数组的“视图”,以便在两个数组之间共享数据。这提供了一种在限制内存使用的同时对阵列数据子集进行操作的强大方式。

牛!NumPy团队发了篇Nature

2.3矢量化

牛!NumPy团队发了篇Nature

为了补充数组语法,NumPy包括对数组执行矢量化计算的函数(代数、统计和三角函数)(d)。矢量化-对整个数组而不是对其单个元素进行操作-对于数组编程至关重要。这意味着在C等语言中需要数十行代码才能表达的操作通常可以实现为一个清晰的Python表达式。这会产生简洁的代码,使用户能够专注于分析的细节,而NumPy则以近乎最佳的方式处理数组元素的循环-例如,考虑跨度以最大限度地利用计算机的高速缓存内存。

2.4广播

牛!NumPy团队发了篇Nature

在对两个形状相同的数组执行向量化操作(如加法)时,应该发生什么是很清楚的。通过“广播”,NumPy允许维度不同,并产生很直觉的结果。一个例子是向数组添加标量值,但是广播也可以推广到更复杂的例子,比如缩放数组的每一列或生成坐标网格。在广播中,一个或两个数组被虚拟复制(即不复制存储器中的任何数据),使得操作数的形状匹配(d)。当使用索引数组对数组进行索引时,也可以应用广播(c)。

2.5缩减

牛!NumPy团队发了篇Nature

其他函数,如sum、mean和maximum,执行逐个元素的“缩减”,跨单个数组的一个、多个或所有轴聚合结果。例如,对d个轴上的n维数组求和得到维数为n-d的数组(f)。

NumPy还包括array-aware函数,用于创建、重构、连接和填补数组;搜索、排序和计数;以及读取和写入文件。它为生成伪随机数提供广泛支持,包括各种概率分布。总之,简单的数组表示、类似数学的语法和各种实用函数使之成为一种高效且强大的数组编程语言。

3 Scientific Python ecosystem

牛!NumPy团队发了篇Nature

Python是一种开源的通用解释型编程语言,非常适合标准编程任务,如清理数据、Web交互和解析文本。添加快速数组运算和线性代数使科学家能够在一种编程语言中完成所有工作-这种编程语言的优势是非常容易学习和教授,许多大学采用这种编程语言作为主要学习语言就证明了这一点。

SciPy, Matplotlib和NumPy在历史、发展和使用上是紧密耦合的。SciPy为科学计算提供基本算法,包括数学、科学和工程惯例。Matplotlib生成可供发布的图形和可视化效果。NumPy、SciPy和Matplotlib的组合,再加上IPython或Jupyter等高级交互环境,为Python中的数组编程提供了坚实的基础。科学Python生态系统(图2)在此基础上构建以提供几个广泛使用的特定于技术的库,这些库又构成许多特定于领域的项目的基础。NumPy是生态系统的基础,它设置了文档标准,提供了数组测试基础设施,并增加了对Fortran和其它编译器的构建支持。

许多研究小组设计了大型、复杂的科学库,为生态系统添加了特定于应用程序的功能。例如,由Event Horizon Telescope Collaboration开发的用于无线电干涉成像、分析和模拟的eht-imaging库依赖于Python科学生态系统的许多较低级别的组件。特别值得一提的是,EHT合作小组利用这个库首次对黑洞进行成像。在eht-imaging中,NumPy阵列用于存储和操作处理链中的每一步的数字数据:从原始数据到校准和图像重建。SciPy提供了用于一般图像处理任务(如过滤和图像对齐)的工具,而SCRICIT-IMAGE(扩展了SciPy的图像处理库)提供了更高级别的功能,如边缘过滤器和霍夫变换。“scipy.Optimize”模块执行数学优化。用于复杂网络分析的软件包NetworkX用于验证图像比较一致性。Astropy处理标准天文文件格式并计算时间坐标转换。Matplotlib用于可视化数据并生成黑洞的最终图像。

由编程基础阵列和周围的工具生态系统创建的交互环境-在IPython或Jupyter内部-非常适合探索性数据分析。用户可以流畅地检查、操作和可视化他们的数据,并快速迭代以改进编程语句。然后将这些语句缝合成命令式或函数式程序,或者包含计算和叙述的笔记本。除了探索性工作之外,科学计算通常是在文本编辑器或集成开发环境(IDE)(如Spyder)中完成的。这种丰富而富有成效的环境让Python在科学研究中大行其道。

最近数据科学、机器学习和人工智能的快速增长进一步戏剧性地推动了Python的科学使用。其重要应用的例子,例如eht-imaging库,现在几乎存在于自然科学和社会科学的每一门学科中。这些工具已经成为许多领域的主要软件环境。NumPy及其生态系统通常在大学课程、训练营和暑期学校授课,是世界各地社区会议和研讨会的焦点。NumPy及其API已经变得无处不在。

牛!NumPy团队发了篇Nature

第一张黑洞图像 by EHT in 2017

4 Array proliferation and interoperability

NumPy在CPU上提供内存中的多维同构类型(即单指针和跨距)数组。它运行在从嵌入式设备到超级计算机的各种机器上,性能接近编译语言。在其存在的大部分时间里,NumPy解决了绝大多数数组计算案例。

然而,科学数据集现在通常会超过一台机器的内存容量,可能会存储在多台机器上,也可能存储在云中。此外,最近加速深度学习和人工智能应用的需要导致了专用加速器硬件的出现,包括图形处理单元(GPU)、张量处理单元(TPU)和现场可编程门阵列(FPGA)。由于其内存数据模型,NumPy目前无法直接利用这种存储和专用硬件。然而,分布式数据以及GPU、TPU和FPGA的并行执行都很好地映射到阵列编程的范例:因此,导致可用的现代硬件架构与利用其计算能力所需的工具之间存在差距。

社区为填补这一空白所做的努力导致了新数组实现的激增。例如,每个深度学习框架都创建了自己的数组。PyTorch 、TensorFlow 、Apache MXNet和JAX数组都能够以分布式方式在CPU和GPU上运行,并使用惰性评估来实现额外的性能优化。SciPy和PyData/Sparse都提供稀疏数组,这些稀疏数组通常包含很少的非零值,并且为了提高效率,只将这些值存储在内存中。此外,还有一些项目将NumPy数组构建为数据容器,并扩展其功能。分布式数组是通过Dask实现的,并通过xarray标记数组,按名称而不是按索引引用数组的维度,通过xarray将x[:, 1] 与 x.loc[:, 'time']进行比较。

这类库通常模仿NumPy API,因为这降低了新手进入的门槛,并为更广泛的社区提供了稳定的编程接口阵列。这反过来又防止了分歧,如numeric和numarray之间的分歧。但是探索使用数组的新方法本质上是实验性的,事实上,几个很有前途的库(如Theano和Caffe)已经停止了开发。每次用户决定尝试一项新技术时,他们都必须更改import语句,并确保新的库实现了他们当前使用的NumPy API的所有部分。

理想情况下,使用NumPy函数或语义对专用数组进行操作会很简单,这样用户只需编写一次代码,然后就可以根据需要在NumPy数组、GPU数组、分布式数组等之间进行切换。为了支持外部数组对象之间的数组操作,NumPy因此增加了使用明确指定的API(图2)充当中央协调机制的功能。

牛!NumPy团队发了篇Nature

为了促进这种互操作性,NumPy提供了“协议”,允许将专门的数组传递给NumPy函数(图3)。NumPy则根据需要将操作分派到原始库。支持400多个最流行的NumPy函数。这些协议由广泛使用的库实现,如Dask、CuPy、xarray和PyData/Sparse。例如,多亏了这些发展,用户现在可以使用Dask将他们的计算从单机扩展到分布式系统。这些协议也很好地组合在一起,允许用户在分布式的多GPU系统上大规模地重新部署NumPy代码,例如,通过嵌入到Dask数组中的CuPy数组。使用NumPy的高级API,用户可以在具有数百万核的多个系统上利用高度并行的代码执行,所有这些都只需最少的代码更改。

这些阵列协议现在是NumPy的一个关键功能,预计其重要性只会增加。NumPy开发人员-其中许多人是这篇评论的作者-迭代地改进和添加协议设计,以提高实用性和简化采用。

5 讨论

NumPy将数组编程的表现力、C语言的性能以及Python的可读性、可用性和通用性结合在一个成熟的、经过良好测试的、有良好文档的、由社区开发的库中。科学Python生态系统中的库提供了大多数重要算法的快速实现。在需要极度优化的地方,可以使用编译语言,如Cython、Numba和Pythran;这些语言扩展了Python并透明地加速了瓶颈。由于NumPy的简单内存模型,很容易编写低级的、手工优化的代码,通常用C或Fortran来操作NumPy数组,并将它们传回Python。此外,使用数组协议,可以在对现有代码进行最小改动的情况下,利用全方位的专用硬件加速。

NumPy最初是由学生、教师和研究人员开发的,目的是为Python提供一个先进的、开源的数组编程库,它可以免费使用,不受许可证服务器和软件保护加密狗的限制。我们有一种共同建设一些有意义的东西以造福于他人的感觉。在一个由志同道合的人组成的友好社区中参与这样的努力,对许多早期贡献者具有强大的吸引力。

这些用户开发者经常不得不从头开始写代码来解决他们自己或同事的问题--通常是用在 Python 之前的低级语言,如 Fortran 和 C。这个新工具的设计参考了其他强大的科学计算交互式编程语言,如Basis,Yorick,R和APL,以及商业语言和环境,如IDL(交互式数据语言)和MATLAB。

起初只是尝试在Python中添加一个数组对象,后来成为一个充满活力的工具生态系统的基础。现在,大量的科学工作依赖于NumPy的正确、快速和稳定。它不再是一个小型的社区项目,而是核心的科学基础设施。

开发者文化已经成熟:虽然最初的开发是高度非正式的,但NumPy现在已经有了一个路线图,以及提出和讨论大型变化的过程。该项目有正式的治理结构,并由NumFOCUS提供财政赞助,NumFOCUS是一个非营利性组织,旨在促进研究、数据和科学计算的开放实践。在过去的几年里,该项目吸引了它的第一个资助开发,由摩尔和斯隆基金会赞助,并作为陈-扎克伯格倡议的开源软件要点计划的一部分获得了一个奖项。在这笔资金的支持下,该项目能够在多个月的时间里持续关注,实现实质性的新功能和改进。尽管如此,NumPy的开发仍然在很大程度上依赖于研究生和研究人员在业余时间做出的贡献。

NumPy不再仅仅是科学Python生态系统的基础数组库,它已经成为张量计算的标准API,也是Python中数组类型和技术之间的核心协调机制。我们还在继续努力扩展和改进这些互操作性功能。

在未来十年,NumPy开发者将面临几个挑战。新的设备将被开发出来,现有的专用硬件也将不断发展,以应对摩尔定律的收益递减。将会有更多、更广泛的数据科学从业者,其中很大一部分将使用NumPy。随着光片显微镜和大型巡天望远镜(LSST)等设备和仪器的采用,科学数据收集的规模将继续扩大。新一代语言、解释器和编译器,如Rust、Julia和LLVM,将创造新的概念和数据结构,并决定其可行性。

通过这篇评论中描述的机制,NumPy已经准备好迎接这样一个不断变化的环境,并继续在交互式科学计算中发挥领导作用,尽管这样做需要政府、学术界和工业界的持续资助。但重要的是,NumPy要想满足数据科学下一个十年的需求,还需要新一代的研究生和社区贡献者来推动它的发展。

部分机器翻译可能有误,原文请戳阅读更多 [1]

参考资料

[1]

https://www.nature.com/articles/s41586-020-2649-2

numpy教程

[1] 官网 https://numpy.org/[2] NumPy中文网 https://www.numpy.org.cn/[3] 官方文档的参考书籍《Guide to Numpy》https://ia803206.us.archive.org/13/items/NumPyBook/NumPyBook.pdf

继续阅读