Python数据API标准联盟

2020-08-19 08:36:37

在过去的几年里,Python在数据科学、机器学习、深度学习和数值计算方面大受欢迎。每年都有新的框架涌现,推动着这些领域的最新发展。所有这些活动和创造力的一个意想不到的后果是,支撑整个Python数据生态系统的基本构建块(多维数组(张量)和数据框库)出现了碎片化。例如,数组在TensorFlow、PyTorch、NumPy、CuPy、MXNet、Xarray、Dask等之间分段。数据帧在Pandas、PySpark、CuDF、Vaex、Modin、Dask、Ibis、Apache Arrow等之间分段。这种碎片化带来了巨大的成本,从为不同阵列或数据框库重新实施整个库,到最终用户在从一个框架移动到另一个框架时重新学习API和最佳实践。

今天,我们宣布成立Python数据API标准联盟,旨在通过开发阵列API标准(也称为。张量)和数据帧。我们的目标是将这个联盟发展成为一个在API、数据交换机制和其他类似主题上进行跨项目和跨生态系统调整的组织。这些主题需要重新协调和沟通的程度远远大于它们需要技术创新的程度。我们的目标是促进前者,而把创新留给现在和未来的单个图书馆。

想要立即开始吗?使用python-record-api收集您自己的API使用情况数据。对于阵列或数据帧维护人员:我们想听听您的想法--请看本文的结尾。

目标是雄心勃勃的,而且存在明显的障碍,比如回答诸如“技术决定对每个图书馆有什么影响?”这样的问题。需要进行大量的工程和技术写作,以创建可用于回答这些问题的概述和数据。这需要专门的时间,因此需要资金,此外,还需要将图书馆的维护人员召集在一起,提供投入并评估这些概览和数据。这些因素促使我们采取以下方法来引导财团:

召集一个由感兴趣的公司(他们帮助资助所需的工程和技术编写时间)和主要社区贡献者组成的联盟。

组成一个工作组,每周开会一小时,设定高级目标、需求和用户故事,并做出初步决策。

几名有足够带宽的工程师将承担建造所需工具的重任,并准备工作组所需的数据和文件草稿。根据工作组的反馈,根据需要进行迭代。

一旦API标准草案有了具体的大纲,就要求更广泛的数组和数据框库维护人员提供输入。这就是我们今天所处的位置。

一旦API标准的工具或草案变得足够成熟,可以进行更广泛的审查,就可以将它们作为征求意见(RFC)发布,并有一个公开的审查过程。根据需要再次迭代。

一旦RFC获得了足够的支持,并且很明显项目能够并愿意采用提议的API,就发布该标准的1.0版本。

这种渐进的RFC过程有点像实验。像NumPy和Pandas这样的社区项目不习惯这种方式;然而,它类似于其他社区的成功模型(例如,开放地理空间联盟,或C++标准化),我们认为涉及的项目的广度和挑战的复杂性使得这是最有希望和最有可能成功的方法。不过,根据经验和来自许多利益相关者的反馈,该方法肯定会随着时间的推移而发展。

在生态系统中还发生了与该联盟相关的其他协同活动,个别成员正在做出贡献,例如开发NumPy阵列协议的工作,以及__dataframe__数据交换协议设计。__array_module__NEP中关于“NumPy的API的受限子集”的部分概述了如何采用我们正在开发的API标准。__dataframe__协议试图解决一个小的、定义明确的问题。__dataframe__协议尝试解决一个小的、定义良好的问题。__dataframe__协议尝试解决一个小的、定义明确的问题。__array_module__nep中关于如何采用我们正在开发的API标准的概述。__dataframe__协议试图解决一个定义明确的小问题。

当我们开始谈论“API标准”或正式规范时,重要的是首先解释我们为什么需要它以及“API标准”的含义。“标准”是一个负载很大的词,而“标准化”是一个过程,如果处理得当,可以产生很大的影响,但也可能唤起过去并不总是富有成效的经验。

当谈到库之间的兼容性时,例如“Pandas、Daskand Vaex Groupby方法是兼容的”,我们暗示各自的DataFrame对象都有一个具有相同签名和相同语义的Groupby方法,因此它们可以互换使用。

目前,数组和DataFrame库都有类似的API,但差别很大,无法真正互换使用。下面是一个相对简单的函数的具体示例,意思是for array:

Numpy:Mean(a,轴=None,dtype=None,Out=None,Keepdims=<;no value>;)Dask。ARRAY:Mean(a,Axis=None,dtype=None,Out=None,Keepdims=<;no value>;)cupy:Mean(a,Axis=None,dtype=None,Out=None,Keepdims=False)JAX。Numpy:Mean(a,Axis=None,dtype=None,Out=None,Keepdims=False)mxnet。NP:均值(a,轴=无,dtype=无,OUT=无,Keepdims=FALSE)稀疏:s。Mean(AXIS=NONE,Keepdims=False,dtype=None,Out=None)手电筒:Mean(INPUT,DIM,Keepdim=False,Out=None)TensorFlow:Reduce_Mean(INPUT_TENSOR,AXIS=NONE,Keepdims=None,Name=None,Reduce_Index=None,Keep_Dims=None)

除了(1)TensorFlow将其称为Reduce_Mean,以及(2)PyData Sparse使用Mean方法而不是函数(它确实可以通过数组协议使用np.Mean)之外,所有的库都在名为Mean的函数中提供此功能。

NumPy、Dask、CuPy、JAX和MXNet具有兼容的签名(除了<;no_value>;Keepdims的默认值,这实际上意味着False,但数组子类的行为不同)。

语义比较难检查,但也会有差异。例如,MXNet文档:此函数与原始的数字在以下方面不同:-仅接受ndarray作为有效输入,不支持pythoniterables或标量-整数输入的默认数据类型为float32。

语义,包括角例(例如NaN、Inf、空数组等)由参考测试套件给出。

函数的语义是一个很大的主题,因此指定的内容的范围必须非常清楚。例如(这可以单独指定,因为它在许多功能之间是通用的):

作用域中只有数组输入,函数可能接受也可能不接受列表、元组或其他对象。

涵盖的数据类型有int32、int64、float16、float32、float64;扩展精度浮点和复杂数据类型、日期时间和自定义类型不在范围之内。

缺省数据类型可以是float32或float64;这是一致的库范围的选择(基本原理:对于深度学习,float32是典型的缺省值,对于一般的数值计算,则是缺省的float64)。

预期结果当输入包含NaN或inf在范围内时,行为可能会略有不同(例如,生成警告),具体取决于实现详细信息。

请注意:以上所有内容都是为了勾勒出“API标准”的含义,具体的签名、语义和作用域可能会而且很可能会发生变化。

我们采用的方法包括设计讨论、需求工程和数据驱动决策的组合。

当许多人在几年的时间跨度内添加功能并解决自己的问题时,当库的API以有机方式增长时,经常缺少的东西是需求工程。含义:从定义明确的范围和用例开始,从这些用例派生需求,然后在做出单独的技术设计决策时参考这些用例和需求。我们的目标是采取这样一种方法,最终实现一致的设计,并为决策提供良好的、有文档记录的理由。

我们需要仔细定义范围,包括目标和非目标。例如,虽然我们的目标是使数组库和数据帧库兼容,以便这些数据结构的使用者能够支持多个这样的库,但无需测试或对消耗的库进行任何更改就可以进行运行时切换并不是我们的目标。一个具体的例子:我们的目标是使SCRKIT-学习使用纯Python代码中的CuPy数组、JAX和PyTorch张量成为可能(作为第一个目标;C/C++/Cython是一个更难破解的难题),但是我们预计这需要做一些修改,并且可能需要在SCRICKIT-LEARN中使用特殊的大小写-因为详细说明SCRICIT-LINE可能依赖的每一个最后的实现是不可行的。

标准只有在被广泛遵守的情况下才有价值。这意味着我们只应该尝试标准化已经有了广泛经验的功能,并且所有的库要么已经有了某种形式,要么可以通过合理的努力来实现,这就意味着我们应该只尝试标准化那些已经有了广泛经验的功能,或者所有的库都已经有了某种形式,或者可以通过合理的努力来实现。因此,将会有更多的整合而不是创新-根据定义,新的东西几乎很难标准化。

在讨论任何单个函数、方法或对象时,我们可能会遇到两个主要问题:

为了回答这些问题,我们构建了两套用于API比较和收集遥测数据的工具,我们今天将在MIT许可证(我们将用于所有代码和文档的许可证)下发布这些工具:

数组-API-比较采用解析来自数组库的所有公共HTML文档的方法,并编译存在/不存在功能及其签名的概述,并将结果呈现为HTML表。只需一个make命令即可找到共同之处或不同之处;例如,所有库中当前函数的交集可以通过make view-interlution获得:

Python-Record-API采用基于竞速的方法。它能够记录运行amodule或运行pytest时从一个指定模块到另一个模块的所有函数调用。它不仅能够确定调用了哪些函数,而且还可以确定使用了哪些关键字,以及所有输入参数的类型。它将运行任何代码库(如消费库的测试套件)的结果存储为JSON。Pandas、Matplotlib、SCISKIT-LEARN、XARRAY和SCRICKIT-IMAGE使用NumPy的初始结果存储在存储库中,并且可以递增添加更多结果。它可以做的下一件事是获取该数据,并根据实际使用情况从该数据合成API。这样一个生成的API可能需要管理和更改,但在讨论API标准中应该包括什么和不应该包括什么时,这是一个非常有用的数据点。

Def sum(a:对象,轴:UNION[NONE,INT,Tuple[UNION[INT,NONE],...]]=...,OUT:UNION[Numpy.。Ndarray,麻木。Float64]=...,dtype:Union[type,None]=...,Keepdims:bool=...,):";";";usage.pandas:38 usage.skimage:114 usage.skLearning:397 usage.xarray:75";";";...。

Quansight Labs启动了这项计划,以解决数据结构碎片化的问题。在与潜在赞助商和社区成员的讨论中,它从专注于开发的工作演变为当前的API标准化方法。Quansight Labs是Quansight的一个公益部门,其使命是支持和发展社区驱动的开源项目和生态系统,而Aocus位于PyData堆栈的核心。

创始赞助商是英特尔、微软、D.E.Shaw集团、GoogleResearch和Quansight。我们还邀请了一些关键的社区贡献者,以确保利益相关者项目的代表性。

在平等的基础上参与所有公司驱动的项目:勾画目标,要求参与,并获得50000美元的资金,以便能够支持所需的工程和技术写作。

对于有兴趣但无法赞助的公司驱动型项目,我们邀请了其阵列或数据框库中的一名关键成员加入。

联盟治理存储库中概述了如何制定决策和如何接受新成员的细节,成员和赞助商页面提供了当前参与者的概述。财团如何运作的细节可能会在接下来的几个月里发展-我们仍处于这一努力的开始阶段。

以下是我们希望在未来几个月内完成的大致时间表:

如果您是数组(张量)或数据框库维护人员:我们希望听到您的消息!我们已经开放了一个问题跟踪器以供讨论。如果您有任何想法、问题和顾虑,我们都很乐意听取。

项目将如何采用标准并将其公开给用户,而不会造成重大的向后兼容性破坏?

然而,这些挑战是值得解决的,因为潜在的好处非常大。我们期待着接下来的事情!