NumPy 2.1.0 发行说明#
NumPy 2.1.0 提供了对即将发布的 Python 3.13 发行版的支持,并不再支持 Python 3.9。除了常规的错误修复和更新的 Python 支持之外,它还有助于我们回到 2.0 的扩展开发后的常规发行周期。此发行版的亮点包括
支持 array-api 2023.12 标准。
支持 Python 3.13。
初步支持自由线程的 Python 3.13。
此版本支持 Python 版本 3.10-3.13。
新增函数#
新函数 numpy.unstack
#
增加了新函数 np.unstack(array, axis=...)
,用于沿一个轴将一个数组拆分为多个数组的元组。它相当于 numpy.stack
的逆操作。
(gh-26579)
弃用#
过期的已弃用项#
C API 更改#
从 npy_3kcompat.h 中移除了许多垫片程序#
许多旧的垫片程序和帮助器函数已从 npy_3kcompat.h
中移除。如果您需要这些内容,则将该文件的前一版本添加至您的代码库中。
(gh-26842)
新的 PyUFuncObject
字段 process_core_dims_func
#
向结构 PyUFuncObject
添加了字段 process_core_dims_func
。对于广义 ufunc,可将此字段设置为类型为 PyUFunc_ProcessCoreDimsFunc
的函数,在调用 ufunc 时将调用此函数。它允许 ufunc 作者检查核心维度是否满足其他约束,并在未提供这些维度时设置输出核心维度大小。
(gh-26908)
新特性#
初步支持免线程 CPython 3.13#
CPython 3.13 将作为实验性免线程版本发布。请参阅 https://py-free-threading.github.io、PEP 703 和 CPython 3.13 版本说明,了解更多关于免线程 Python 的详细信息。
NumPy 2.1 初步支持 CPython 3.13 的免线程版本。此支持通过修复 NumPy 中的许多 C 线程安全性问题来实现。在 NumPy 2.1 之前,NumPy 使用大量 C 全局静态变量来存储运行时缓存和其他状态。我们已经重构以避免需要全局状态,将全局状态转换为线程局部状态或添加锁定。
支持免线程 Python 并不意味着 NumPy 是线程安全的。对 ndarray 的只读共享访问应该是安全的。NumPy 公开了共享的可变状态,我们没有向数组对象本身添加任何锁定来序列化对共享状态的访问。在用户代码中必须小心,避免在多线程中修改同一个数组时发生竞争。在多线程中同时修改数组肯定可以使 NumPy 崩溃,例如同时调用 ufunc 和 resize
方法。目前我们的指导原则是:“不要这样做”。将来我们希望提供更有力的保证。
对象数组尤其需要特别小心,因为 GIL 以前为对象数组访问提供了锁定,但不再提供。请参阅 问题 #27199,了解更多关于免线程版本中的对象数组的信息。
如果您对免线程 Python 感兴趣,例如因为您有一个基于多进程的工作流,并且您感兴趣的是用 Python 线程运行它,我们鼓励您进行测试和试验。
如果您怀疑遇到了 NumPy 导致的问题,请 创建一个问题,首先检查该错误是否也发生在“常规”非自由线程 CPython 3.13 版本中。许多线程错误也可能在释放 GIL 的代码中发生;禁用 GIL 只能让发现线程错误变得更容易。
(gh-26157)
numpy.reshape
和numpy.ndarray.reshape
现在支持shape
和copy
参数。(gh-26292)
NumPy 现在支持 DLPack v1,将来不再支持旧版本。
(gh-26501)
numpy.asanyarray
现在支持copy
和device
参数,与numpy.asarray
相匹配。(gh-26580)
numpy.printoptions
、numpy.get_printoptions
和numpy.set_printoptions
现在支持一个新选项override_repr
,用于定义自定义repr(array)
行为。(gh-26611)
numpy.cumulative_sum
和numpy.cumulative_prod
已作为 Array API 兼容替代品添加,用于numpy.cumsum
和numpy.cumprod
。新函数可以在结果中包含一个固定初始值(sum
为零,prod
为一)。(gh-26724)
numpy.clip
现在支持max
和min
关键字参数,旨在替换a_min
和a_max
。而且,对于np.clip(a)
或np.clip(a, None, None)
,将返回输入数组的副本,而不是引发错误。(gh-26724)
numpy.astype
现在支持device
参数。(gh-26724)
f2py
可以生成与 freethreading 兼容的 C 扩展#
将--freethreading-compatible
传递到 f2py CLI 工具,以生成标记为与 free threading CPython 解释器兼容的 C 扩展。这样做可防止解释器在导入 C 扩展时在运行时重新启用 GIL。请注意,f2py
不会分析 fortran 代码的线程安全性,因此在将扩展标记为兼容之前,必须验证所包装的 fortran 代码是线程安全的。
(gh-26981)
改进#
histogram
自动分区现在返回对于整数输入数据而言大于等于 1 的分区大小#
对于整数输入数据,小于 1 的分区大小会导致虚假的空分区。现在在使用 histogram_bin_edges
提供的算法之一计算分区数量时,可以避免这种情况。
(gh-12150)
ndarray
形状类型参数现在协变并绑定到tuple[int, ...]
#
ndarray
的静态类型化是一项长期工作,其中包含此更改。它是一个通用类型,具有形状和数据类型的类型参数。以前,形状类型参数可以是任何值。此更改将它限制为整型的元组,正如从ndarray.shape
中可以预料的那样。此外,形状类型参数已从不变体更改为协变体。此更改也适用于ndarray
的子类型,例如numpy.ma.MaskedArray
。有关详细信息,请参阅typing 文档。
(gh-26081)
np.quantile
使用closest_observation
方法选择最近的偶数阶统计量#
这更改了边界案例最近的定义,从最近奇数阶统计量更改为最近偶数阶统计量。Numpy 实现现在匹配其他参考实现。
(gh-26656)
lapack_lite
现在是线程安全的#
NumPy 提供了最小低性能 LAPACK 版本,名为 lapack_lite
,可在构建时未检测到任何 BLAS/LAPACK 系统时使用。
到目前为止,lapack_lite
并非线程安全的。单线程用例不会遇到任何问题,但在多线程中运行线性代数操作会导致错误、不正确的结果或段错误,原因是数据竞争。
我们添加了一个全局锁,序列化对 lapack_lite
的多线程访问。
(gh-26750)
numpy.printoptions
上下文管理器现在是线程和异步安全的#
在 NumPy 的早期版本中,printoptions 是使用 Python 和 C 全局变量的组合来定义的。我们重新设计了该状态,它存储在 python ContextVar
中,从而使上下文管理器是线程和异步安全的。
(gh-26846)
类型提示 numpy.polynomial
#
从 2.1 版本开始,numpy.polynomial
及其子包中的函数和便利类已包含 PEP 484 类型注释。
(gh-26897)
改进的 numpy.dtypes
类型提示#
numpy.dtypes
的类型注释现在能更好地反映运行时:numpy.dtype
类型别名已替换为专门的 dtype
子类型,以前 numpy.dtypes.StringDType
的丢失注释也已添加。
(gh-27008)
性能改进和变更#
numpy.save
现在使用 pickle 协议版本 4 来保存具有对象数据类型(dtype)的数组,这允许 pickle 对象大于 4GB,并为大型数组提高了大约 5% 的保存速度。(gh-26388)
在 x86_64 和 i686 上的 OpenBLAS 使用更少的内核构建。根据基准测试,这些内核周围有 5 个性能集群:
PRESCOTT NEHALEM SANDYBRIDGE HASWELL SKYLAKEX
。(gh-27147)
针对 Windows 上的 OpenBLAS 进行链接时,不会使用 quadmath,从而简化了许可
(gh-27147)
由于 Windows 上 OpenBLAS 中的回归,OpenBLAS 0.3.26 使用多个线程时的性能改进被还原了。
(gh-27147)
ma.cov
和 ma.corrcoef
现在显著更快#
专用函数已经过重构,以及 ma.cov
和 ma.corrcoef
。它们现在明显变快了,尤其是在大型掩模数组上。
(gh-26285)
更改#
由于
numpy.vecdot
现在是 ufunc,因此其签名不够精确。这是由于 ufunc 输入存根的限制。(gh-26313)
numpy.floor
、numpy.ceil
和numpy.trunc
现在不会对整数和布尔数据类型(dtype)输入数组执行强制转换为浮点数据类型。(gh-26766)
ma.corrcoef
可能返回稍有不同的结果#
当前在 ma.corrcoef
中采用成对观测方法来计算每对变量的标准差。现在已对此进行更改,因为它用于对协方差进行标准化,而协方差是使用 ma.cov
进行估计的,后者不会对每对变量的观测进行考虑,因此没有必要进行标准化。标准化现已替换为每对变量更合适的标准差,这显著减少了内存消耗时间,但在变量对之间的观测值没有对齐的情况下,将返回稍有不同的相关系数估计值。但它将在所有其他情况下返回相同的估计值,包括在使用无掩码值的掩码数组时返回与 corrcoef
相同的相关矩阵。
(gh-26285)
copyto
和 full
中的类型安全修复#
copyto
现在正确使用了 NEP 50,并将其应用于其类型安全性。Python 整数到 NumPy 整数的转换以及 Python 浮点数到 NumPy 浮点数的转换现在都被视为“安全”,即使赋值可能会失败或精度可能会下降。这意味着以下示例会略有变更
np.copyto(int8_arr, 1000)
之前执行过不安全/同类型转换Python 整数。现在它总是会引发,若要实现不安全的转换,必须传递数组或 NumPy 标量。
np.copyto(uint8_arr, 1000, casting="safe")
会引发 TypeError,而不是 OverflowError,原因是同类型转换。np.copyto(float32_arr, 1e300, casting="safe")
会溢出到inf
(float32 无法保存1e300
),而不是引发 TypeError。
此外,仅在指定 NumPy 标量(或 0 维数组)时才使用数据类型,这意味着以下行为不同
np.copyto(float32_arr, np.float64(3.0), casting="safe")
会引发异常。np.coptyo(int8_arr, np.int64(100), casting="safe")
会引发异常。之前,NumPy 检查过 100 是否适合int8_arr
。
这使得 copyto
、full
和 full_like
与 NumPy 2 正确的行为保持一致。
(gh-27091)