NumPy 路线图#
这是我们计划投入资源的任务和功能的实时快照。它可用于鼓励和激励开发者,并寻求资金。
互操作性#
我们的目标是让 NumPy 更易于互操作。有许多类似 NumPy 的包为 Python 生态系统增加了有趣的新功能,也有许多库以各种方式扩展了 NumPy 的模型。NumPy 中旨在促进与所有此类包及其使用代码互操作的工作可能包括(但不限于)互操作协议、更好的鸭子类型支持和 ndarray 子类处理。
关键目标是:让为 NumPy 编写的代码也能与其他类似 NumPy 的项目配合使用。这将通过 CuPy、JAX 或 PyTorch 等实现 GPU 支持,通过 Dask 实现分布式数组支持,以及编写与 SciPy、scikit-learn 和其他此类包良好协作的专用数组(无论是从头开始编写,还是作为 numpy.ndarray
子类)。NumPy 2.0 在这方面迈出了重要一步,采用了并符合数组 API 标准(v2022.12,参见 NEP 47 — 采用数组 API 标准)。未来这方面的工作将包括支持更新版本的数组 API 标准,并根据实际经验和需求添加所需功能。
此外,__array_ufunc__
和 __array_function__
协议在此处发挥作用——它们是稳定的,并被多个下游项目使用。
性能#
提升 NumPy 的性能对许多用户很重要。我们已将精力集中在通用 SIMD(参见 NEP 38 — 使用 SIMD 优化指令提升性能)内在函数上,它们通过抽象层在各种硬件平台上提供了良好的改进。基础设施已就位,我们欢迎后续 PR 在相关 NumPy 功能中添加 SIMD 支持。
从 C 到 C++ 的过渡,无论是在 SIMD 基础设施中还是在更广泛的 NumPy 内部,都在进行中。我们还开始使用 Google Highway(参见 NEP 54 — SIMD 基础设施演进:迁移到 C++ 时采用 Google Highway),并且这种使用可能会扩展。对更新的 SIMD 指令集(如 arm64 上的 SVE)的支持工作正在进行中。
其他性能改进思路包括
关于并行执行的更好方案(相关的是对自由线程 CPython 的支持,详见下文)。
使 NumPy 能够使用更快但精度较低的 ufunc 实现。到目前为止,唯一修改 ufunc 行为的状态是
np.errstate
。但是,NumPy 2.0 在np.errstate
和 ufunc C 实现方面的改进使这种添加变得更容易。单个函数中的优化。
此外,我们希望改进基准测试系统,包括覆盖范围、易用性和结果发布。与 main 分支相比的基准测试 PR/分支是主要目的,并且是性能导向 PR(例如,向函数添加 SIMD 加速)所必需的。此外,我们希望有一个像我们这里一样的性能概览,以一种长期更可维护的方式设置。
文档和网站#
NumPy 文档的质量参差不齐。API 文档状况良好;但许多主题的教程和高级文档缺失或过时。有关计划中的改进,请参见 NEP 44 — 重构 NumPy 文档。在 numpy-tutorials 仓库中,正在添加更多教程。
我们还打算使文档中的所有示例代码具有交互性——目前正在通过 jupyterlite-sphinx
和 Pyodide 进行此项工作。NumPy 2.3.0 作为此项工作的试点,提供了示例的交互式文档。
我们的网站(https://numpy.com.cn)状况良好。我们希望进一步扩展网站的翻译语言数量。同时,也希望通过 JupyterLite 改进交互式笔记本小部件。
可扩展性#
我们的目标是继续使 NumPy 更易于扩展。这里的主要议题是改进 dtype 系统——例如参见 NEP 41 — 新数据类型系统的第一步以及由此链接的相关 NEP。在 NumPy 2.0 中,新的用户定义 dtype 的 C API 已公开。我们旨在鼓励其使用并进一步改进此 API,包括支持用 Python 编写 dtype。
可能首先在 NumPy 主仓库之外开发,并可能在以后并入 NumPy 的新 dtype 想法包括
四精度(128位)dtype
一个
bfloat16
dtype支持编码(例如
utf8
或latin1
)的定宽字符串 dtype一个单位 dtype
我们还计划根据需要扩展 ufunc C API。这里的一种可能性是创建一个新的、更强大的 API,以允许接入现有的 NumPy ufunc 实现。
用户体验#
类型注解#
大多数 NumPy 功能的类型注解已完成(尽管像 numpy.ma
这样的一些子模块缺少返回类型),因此用户可以使用 mypy 等工具进行类型检查,IDE 也可以改进对 NumPy 的支持。改进这些类型注解,例如支持注解数组形状(参见 gh-16544),正在进行中。
平台支持#
我们旨在增加对不同硬件架构的支持。这包括在 CI 服务可用时增加 CI 覆盖,为需求量足够的平台在 PyPI 上提供 wheel 包(例如,我们为 NumPy 2.0 添加了 musllinux
包),以及解决我们在 CI 中未测试的平台(例如 AIX)上的构建问题。
我们打算撰写一份 NEP,涵盖我们提供的支持级别以及平台升级到更高支持级别所需的要求,类似于 PEP 11。
进一步修复提升和标量逻辑的一致性#
NumPy 2.0 修复了许多关于类型提升的问题,尤其是在处理标量方面。我们计划继续修复剩余的不一致性。例如,NumPy 会将 0 维对象转换为标量,并且 NumPy 仍然允许的一些类型提升存在问题。
支持自由线程 CPython#
CPython 3.13 将是第一个提供自由线程构建(即禁用 GIL 的 CPython 构建)的版本。目前正在进行工作以在 NumPy 中良好支持此功能。一旦该功能稳定并完成,可能就有机会实际利用自由线程 CPython 带来的性能改进潜力,或者让 NumPy 用户更容易实现这一点。
二进制大小缩减#
NumPy 从 PyPI 和其他平台的下载量持续增长——截至 2024 年 5 月,仅 PyPI 每月下载量就超过 2 亿次。减少已安装 NumPy 包的大小有许多好处:更快的安装、更低的磁盘空间占用、减小 PyPI 上的负载、更小的环境影响、在资源受限的环境和平台(如 AWS Lambda)上更容易在 NumPy 之上安装更多包、降低 Pyodide 用户的延迟等等。我们的目标是显著减小大小,并使最终用户和打包者更容易生成更小的自定义构建(例如,我们在 2.1.0 之前添加了剥离测试的支持)。详情请参见 gh-25737。
支持使用 CPython 的受限 C API#
使用 CPython 的受限 C API,允许生成使用稳定 ABI 的 abi3
wheel 包,从而独立于 CPython 功能发布,这对于使用 NumPy C API 的下游包和 NumPy 本身都有益。在 NumPy 2.0 中,已开展工作以在 NumPy 中通过 Cython 支持启用受限 C API(参见 gh-25531)。需要更多的工作和测试来确保对下游包的完全支持。
我们还希望探索 NumPy 本身使用受限 C API 所需的条件——这将使整个生态系统中测试新的 CPython 开发和预发布版本变得更容易,并显著减少 NumPy 自身 CI 作业的维护工作量。
为 NumPy 创建一个纯头文件包#
我们已将公共 NumPy 头文件中平台相关的内容减少到几乎为零。现在可以创建一个单独的包,其中仅包含 NumPy 头文件及其发现机制,以使下游包无需安装 NumPy 即可针对 NumPy C API 进行构建。这将使得使用 NumPy 的 C API 更容易/更便宜,尤其是在我们不提供 wheel 包的更小众平台上。
NumPy 2.0 稳定性和下游使用#
我们在 NumPy 2.0 中进行了大量的更改(和改进!)。发布过程耗时很长,并且部分生态系统仍在追赶。我们可能需要放慢一段时间,并可能帮助生态系统的其他部分适应 ABI 和 API 的变化。
我们需要评估对 NumPy 本身、下游包作者和最终用户的成本和收益。根据该评估,我们需要得出结论,未来是否现实地再次进行 ABI 破坏性发布。这也将为我们 C API 的未来演进提供信息。
安全性#
NumPy 相当安全——我们收到的关于潜在漏洞的报告数量有限,而且大多数都是不正确的。我们通过文档化的安全策略、私有披露方法和维护 OpenSSF 记分卡(得分很高)取得了进展。然而,我们已经很长时间没有在供应链安全方面做出太多改变。我们旨在在此处进行改进,例如实现我们发布的所有构建产物的完全可复现构建——并为其提供完整的出处信息。
维护#
numpy.ma
仍然状况不佳且维护不足。它需要改进,想法包括重写掩码数组,使其不再是 ndarray 子类——或许在一个单独的项目中?
将 MaskedArray 作为鸭子数组类型,和/或
支持缺失值的 dtypes
制定策略,处理 NumPy 和 SciPy 在
linalg
方面的重叠问题。弃用
np.matrix
(非常缓慢地)——一旦 SciPy 中稀疏矩阵到稀疏数组的转换完成,这便是可行的。为“向量化索引”和“外部索引”添加新的索引模式(参见 NEP 21 — 简化和显式的高级索引)。
使多项式 API 更易于使用。