NumPy 2.3.0 发布说明#

NumPy 2.3.0 版本继续致力于改进对自由线程 Python 的支持和注解,并包含一系列常规错误修复。此次发布不同寻常之处在于大量已过期的弃用、代码现代化和样式清理。后者可能对用户不可见,但对长期代码维护至关重要。另请注意,我们已从 manylinux2014 升级到 manylinux_2_28。

在配备 M4 CPU 的 Mac 上运行的用户可能会看到各种关于无效值等的警告。这些警告是 Accelerate 的已知问题。它们虽然烦人,但无害。苹果承诺会修复它们。

此版本支持 Python 3.11-3.13 版,Python 3.14 发布后将得到支持。

亮点#

  • NumPy 文档中的交互式示例。

  • 使用 OpenMP 并行化构建 NumPy。

  • 对基于 ARM 的 Windows 的初步支持。

  • 改进了对自由线程 Python 的支持。

  • 改进了注解。

新函数#

新函数 numpy.strings.slice#

新增了函数 numpy.strings.slice,它实现了字符串数组的快速原生切片。它支持完整的切片 API,包括负切片偏移和步长。

(gh-27789)

弃用#

  • numpy.typing.mypy_plugin 已被弃用,转而支持平台无关的静态类型推断。请从 mypy 配置的 plugins 部分中移除 numpy.typing.mypy_plugin。如果此更改导致报告新错误,请提交一个问题。

    (gh-28129)

  • numpy.typing.NBitBase 类型已弃用,并将在未来版本中移除。

    此类型以前旨在用作类型参数的通用上限,例如

    import numpy as np
    import numpy.typing as npt
    
    def f[NT: npt.NBitBase](x: np.complexfloating[NT]) -> np.floating[NT]: ...
    

    但在 NumPy 2.2.0 中,float64complex128 更改为具体子类型,导致静态类型检查器拒绝 x: np.float64 = f(np.complex128(42j))

    因此,更好的方法是使用 typing.overload

    import numpy as np
    from typing import overload
    
    @overload
    def f(x: np.complex64) -> np.float32: ...
    @overload
    def f(x: np.complex128) -> np.float64: ...
    @overload
    def f(x: np.clongdouble) -> np.longdouble: ...
    

    (gh-28884)

已过期弃用#

  • 从 Cython 接口中移除诸如 NPY_OWNDATA 等已弃用宏,转而使用 NPY_ARRAY_OWNDATA(自 1.7 版本弃用)

    (gh-28254)

  • 移除 numpy/npy_1_7_deprecated_api.h 和诸如 NPY_OWNDATA 等 C 宏,转而使用 NPY_ARRAY_OWNDATA(自 1.7 版本弃用)

    (gh-28254)

  • 移除 generate_divbyzero_errornpy_set_floatstatus_divbyzero 的别名,以及 generate_overflow_errornpy_set_floatstatus_overflow 的别名(自 1.10 版本弃用)

    (gh-28254)

  • 移除 np.tostring(自 1.19 版本弃用)

    (gh-28254)

  • 对非数字类型使用 np.conjugate 时抛出异常(自 1.13 版本弃用)

    (gh-28254)

  • 使用 np.bincount(...minlength=None) 时抛出异常,请改用 0(自 1.14 版本弃用)

    (gh-28254)

  • 向具有非可选形状参数的函数传递 shape=None 会引发错误,请改用 ()(自 1.20 版本弃用)

    (gh-28254)

  • modesearchside 的不精确匹配会引发异常(自 1.20 版本弃用)

    (gh-28254)

  • 设置 __array_finalize__ = None 会引发错误(自 1.23 版本弃用)

    (gh-28254)

  • np.fromfilenp.fromstring 在遇到错误数据时会引发错误,此前它们会尝试猜测(自 1.18 版本弃用)

    (gh-28254)

  • 使用元组构造 datetime64timedelta64 不再接受 event 值,请使用 (unit, num) 二元组或 (unit, num, den, 1) 四元组(自 1.14 版本弃用)

    (gh-28254)

  • 从具有 dtype 属性的类构造 dtype 时,该属性必须是 dtype 实例,而不是可以解析为 dtype 实例的东西(自 1.19 版本弃用)。在某个时候,使用 dtype 属性的整个构造都将被弃用(参见 #25306)

    (gh-28254)

  • 将布尔值作为分区索引传递会引发错误(自 1.23 版本弃用)

    (gh-28254)

  • 即使在空数组上,越界索引也会引发错误(自 1.20 版本弃用)

    (gh-28254)

  • 已移除 np.tostring,请改用 tobytes(自 1.19 版本弃用)

    (gh-28254)

  • 禁止将基不拥有其数据的不可写数组变为可写(自 1.17 版本弃用)

    (gh-28254)

  • 带有 axis=Noneconcatenate() 默认使用 same-kind 类型转换,而不是 unsafe(自 1.20 版本弃用)

    (gh-28254)

  • 反序列化(unpickling)具有对象 dtype 的标量会引发错误(自 1.20 版本弃用)

    (gh-28254)

  • fromstring 的二进制模式现在会引发错误,请改用 frombuffer(自 1.14 版本弃用)

    (gh-28254)

  • np.inexactnp.floating 转换为 dtype 会引发错误(自 1.19 版本弃用)

    (gh-28254)

  • np.complex, np.integer, np.signedinteger, np.unsignedinteger, np.generic 转换为 dtype 会引发错误(自 1.19 版本弃用)

    (gh-28254)

  • Python 内置的 round 对复数标量会引发错误。请改用 np.roundscalar.round(自 1.19 版本弃用)

    (gh-28254)

  • ‘np.bool’ 标量不再能被解释为索引(自 1.19 版本弃用)

    (gh-28254)

  • 通过浮点字符串解析整数不再受支持。(自 1.23 版本弃用)为避免此错误,您可以 * 确保原始数据存储为整数。 * 使用 converters=float 关键字参数。 * 使用 np.loadtxt(...).astype(np.int64)

    (gh-28254)

  • 对 ufunc signature 使用长度为 1 的元组会引发错误。请使用 dtype 或用 None 填充元组(自 1.19 版本弃用)

    (gh-28254)

  • np.outer 中对矩阵的特殊处理已移除。请通过 matrix.A 转换为 ndarray(自 1.20 版本弃用)

    (gh-28254)

  • 已移除 np.compat 包的源代码(在 2.0 版本中移除)

    (gh-28961)

C API 更改#

  • NpyIter_GetTransferFlags 现在可用于检查迭代器是否需要 Python API 或类型转换是否可能导致浮点错误(FPE)。例如,将 float64(1e300) 转换为 float32(溢出到无穷大)或将 NaN 转换为整数(无效值)时,可能会出现 FPE。

    (gh-27883)

  • NpyIter 现在对其支持的操作数数量没有限制。

    (gh-28080)

新的 NpyIter_GetTransferFlagsNpyIter_IterationNeedsAPI 更改#

NumPy 现在新增了 NpyIter_GetTransferFlags 函数,作为检查迭代器/缓冲需求的更精确方式。即,是否需要 Python API/GIL 或是否可能发生浮点错误。如果您已经知道自己的需求而无需缓冲,此函数也会更快。

NpyIter_IterationNeedsAPI 函数现在执行所有以前在设置时执行的检查。虽然它从来没有必要多次调用,但现在这样做会产生更大的开销。

(gh-27998)

新特性#

  • np.dtype 的类型参数现在默认为 typing.Any。这样,静态类型检查器会将 dtype: np.dtype 推断为 dtype: np.dtype[Any],而不会报告错误。

    (gh-28669)

  • 静态类型检查器现在将

    • _: np.ndarray 解释为 _: npt.NDArray[typing.Any]

    • _: np.flatiter 解释为 _: np.flatiter[np.ndarray]

    这是因为它们的类型参数现在有了默认值。

    (gh-28940)

NumPy 现在将其 pkg-config 路径注册到 pkgconf PyPI 包#

pkgconf PyPI 包提供了一个接口,供 NumPy 等项目注册自己的路径以添加到 pkg-config 搜索路径中。这意味着当从 PyPI 使用 pkgconf 时,NumPy 将无需任何自定义环境配置即可被发现。

注意

注意

这仅适用于从 PyPI 使用 pkgconf 包的情况,换句话说,这仅适用于通过 Python 包管理器安装 pkgconf 的情况。

如果您使用的是系统提供的 pkg-configpkgconf,或者任何不使用 pkgconf-pypi 项目的其他来源,NumPy pkg-config 目录将不会自动添加到搜索路径。在这种情况下,您可能需要使用 numpy-config

(gh-28214)

允许在 ufunc 中使用 out=... 以确保数组结果#

NumPy 有时会表现出一种令人困扰的行为,即它目前通常返回标量而不是 0 维数组(即使输入是 0 维数组)。这对于非数值 dtype(例如 object)来说尤其成问题。

对于 ufunc(即大多数简单的数学函数),现在可以使用 out=...(字面上是 `…`,例如 out=Ellipsis),其行为与不传递 out 相同,但会确保返回非标量。这种写法借鉴了 arr1d[0, ...],其中 ... 也确保返回非标量。

其他带有 out= 关键字参数的函数最终也应获得支持。通过 __array_ufunc____array_function__ 进行互操作的下游库可能需要进行调整以支持此功能。

(gh-28576)

使用 OpenMP 并行化构建 NumPy#

NumPy 现在支持 OpenMP 并行处理功能,当使用 -Denable_openmp=true Meson 构建标志进行构建时。此功能默认禁用。启用后,np.sortnp.argsort 函数可以利用 OpenMP 进行并行线程执行,从而提高这些操作的性能。

(gh-28619)

NumPy 文档中的交互式示例#

NumPy 文档包含一些示例,现在可以使用 WebAssembly 和 Pyodide 在浏览器中交互式运行。

请注意,这些示例目前是实验性的,可能并非适用于公共 API 中的所有方法。

(gh-26745)

改进#

  • 现在,不可比较 dtype 之间的标量比较(例如 np.array(1) == np.array('s'))会返回 NumPy 布尔值而不是 Python 布尔值。

    (gh-27288)

  • np.nditer 现在对其支持的操作数(C 整数)数量没有限制。

    (gh-28080)

  • 现在,任何可以转置为 C 连续数组的数组都支持无拷贝序列化(pickling)。

    (gh-28105)

  • 用户定义的 dtype 的 __repr__ 现在更倾向于使用自定义 dtype 的 __name__,而不是从其 kinditemsize 构造的更通用的名称。

    (gh-28250)

  • np.dot 现在报告浮点异常。

    (gh-28442)

  • np.dtypes.StringDType 现在是一个泛型类型,它接受一个 na_object 的类型参数,该参数默认为 typing.Never。例如,StringDType(na_object=None) 返回 StringDType[None],而 StringDType() 返回 StringDType[typing.Never]

    (gh-28856)

np.isclose 添加了警告#

如果在 np.isclose 中 atol 或 rtol 至少有一个是 np.nannp.inf,则添加了警告消息。

  • 警告遵循用户的 np.seterr 设置

(gh-28205)

性能改进和更改#

np.unique 的性能改进#

np.unique 现在尝试使用哈希表来查找唯一值,而不是在查找唯一值之前对值进行排序。目前这仅限于某些 dtype,并且该函数对于这些 dtype 而言现在更快。该函数现在还暴露了一个 sorted 参数,允许按查找顺序返回唯一值,而不是之后再进行排序。

(gh-26018)

np.sortnp.argsort 的性能改进#

np.sortnp.argsort 函数现在可以利用 OpenMP 进行并行线程执行,在具有 AVX2 或 AVX-512 指令的 x86 架构上,速度可提高达 3.5 倍。此可选功能要求 NumPy 使用 -Denable_openmp Meson 标志构建。用户可以通过设置 OMP_NUM_THREADS 环境变量来控制使用的线程数。

(gh-28619)

np.float16 类型转换的性能改进#

此前,所有平台上的浮点数与 np.float16 类型之间的转换都在软件中模拟。

现在,在支持 Neon float16 内在函数的 ARM 设备上(例如最近的 Apple Silicon),使用原生 float16 路径以实现最佳性能。

(gh-28769)

更改#

  • 向量范数 ord=inf 和矩阵范数 ord={1, 2, inf, 'nuc'} 现在对于空数组总是返回零。空数组至少有一个大小为零的轴。这会影响 np.linalg.normnp.linalg.vector_normnp.linalg.matrix_norm。以前,NumPy 会根据数组的形状引发错误或返回零。

    (gh-28343)

  • 在使用方法 np.format_float_positional 将字符串转换为浮点数时返回的错误消息中的一个拼写错误已得到修复。

    (gh-28569)

  • NumPy 的 __array_api_version__ 已从 2023.12 升级到 2024.12

  • 现在,numpy.count_nonzeroaxis=None(默认)时返回 NumPy 标量而不是 Python 整数。

  • numpy.take_along_axis 函数中的参数 axis 现在默认值为 -1

    (gh-28615)

  • 通过根据浮点精度调整向科学记数法的转换,改进了 np.float16np.float32 标量和数组的打印。为了向后兼容,新增了一个旧版 np.printoptions 模式 '2.2'

    (gh-28703)

  • 现在,如果字符串与整数相乘的结果会创建一个过大的字符串而无法表示,则会引发 OverflowError 而不是 MemoryError。这遵循 Python 的行为。

    (gh-29060)

unique_values 可能返回未排序的数据#

相对较新的函数(在 NumPy 2.0 中添加)unique_values 现在可能返回未排序的结果。就像 unique_countsunique_all 从未保证排序结果一样,尽管到目前为止结果一直是排序的。在这些函数确实返回排序结果的情况下,未来版本中可能会改变以提高性能。

(gh-26018)

主迭代器和潜在数值更改#

主要迭代器(在数学函数中使用,并通过 Python 中的 np.nditer 和 C 中的 NpyIter 使用)现在对于某些缓冲迭代的行为有所不同。这意味着

  • 使用的缓冲区大小通常会小于 buffersize 参数允许的最大缓冲区大小。

  • 当没有操作数需要缓冲时,带有缓冲约简的“growinner”标志现在得到遵守。

对于 np.sum(),缓冲区大小的此类更改可能会轻微改变浮点运算的数值结果。使用“growinner”进行自定义约简的用户可能会注意到精度上的变化(例如,在 NumPy 中,我们从 einsum 中移除了它,以避免大多数精度变化并提高某些 64 位浮点输入的精度)。

(gh-27883)

最低支持的 GCC 版本现在是 9.3.0#

最低支持版本已从 8.4.0 更新到 9.3.0,主要是为了减少旧 GCC 版本中平台特定错误导致问题的可能性。

(gh-28102)

numpy.histogram 中自动 bin 选择的更改#

numpy.histogram 中的自动 bin 选择算法已修改,以避免对于低变异样本出现内存不足错误。要完全控制所选的 bin,用户可以使用 numpy.histogrambinrange 参数。

(gh-28426)

构建 manylinux_2_28 wheels#

Linux 系统的 Wheels 将使用 manylinux_2_28 标签(而不是 manylinux2014 标签),这意味着根据 PEP 600 支持表,放弃对 redhat7/centos7、amazonlinux2、debian9、ubuntu18.04 和其他早于 glibc2.28 的操作系统版本的支持。

(gh-28436)

移除在 macOS 上使用 -Wl,-ld_classic#

移除在 macOS 上使用 -Wl,-ld_classic。Spack 不再需要此技巧,而且它会导致库无法链接到使用 ld(新)构建的其他库。

(gh-28713)

重新启用 numpy.strings 中的函数覆盖#

重新启用 numpy.strings 模块中的函数覆盖。

(gh-28741)