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
#
字段 process_core_dims_func
被添加到结构 PyUFuncObject
中.对于广义的 ufuncs,可以将此字段设置为类型为 PyUFunc_ProcessCoreDimsFunc
的函数,当调用 ufunc 时将调用该函数.它允许 ufunc 作者检查核心维度是否满足额外的约束,并在未提供输出核心维度大小时设置它们.
(gh-26908)
新特性#
对自由线程 CPython 3.13 的初步支持#
CPython 3.13 将作为实验性的自由线程构建版提供.请参阅 https://py-free-threading.github.io,`PEP 703 <https://peps.python.org/pep-0703/>`_ 和 CPython 3.13 发布说明 以了解更多关于自由线程 Python 的详细信息.
NumPy 2.1 对 CPython 3.13 的自由线程构建提供了初步支持.这一支持是通过修复 NumPy 中大量 C 线程安全问题实现的.在 NumPy 2.1 之前,NumPy 使用了大量 C 全局静态变量来存储运行时缓存和其他状态.我们已经重构以避免全局状态的需要,将全局状态转换为线程局部状态,或添加了锁定.
支持自由线程的 Python 并不意味着 NumPy 是线程安全的.对 ndarray 的只读共享访问应该是安全的.NumPy 暴露了共享的可变状态,我们没有在数组对象本身添加任何锁定来序列化对共享状态的访问.如果在多个线程中想要改变同一个数组,用户代码必须小心避免竞争条件.通过在多个线程中同时改变一个数组,例如同时调用一个 ufunc 和 resize
方法,肯定有可能使 NumPy 崩溃.目前我们的建议是:”不要这样做”.未来我们希望能提供更强的保证.
特别是对象数组需要特别注意,因为GIL之前为对象数组访问提供了锁定,现在不再提供.有关自由线程构建中的对象数组的更多信息,请参见 Issue #27199.
如果你对自由线程的Python感兴趣,例如因为你有一个基于多进程的工作流,你希望用Python线程来运行,我们鼓励测试和实验.
如果你遇到的问题你怀疑是因为NumPy,请 提交一个issue ,首先检查一下这个bug是否也发生在”常规”的非自由线程的CPython 3.13构建中.许多线程bug也可能发生在释放GIL的代码中;禁用GIL只会更容易触发线程bug.
(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
作为与数组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
可以生成兼容自由线程的 C 扩展#
传递 --freethreading-compatible
给 f2py CLI 工具以生成一个标记为兼容自由线程 CPython 解释器的 C 扩展.这样做可以防止解释器在导入 C 扩展时在运行时重新启用 GIL.请注意,``f2py`` 不会分析 fortran 代码的线程安全性,因此你必须在将扩展标记为兼容之前验证包装的 fortran 代码是线程安全的.
(gh-26981)
改进#
histogram
自动分箱现在对整数输入数据返回 >=1 的分箱大小#
对于整数输入数据,小于1的箱子大小会导致虚假的空箱子.现在,当使用 histogram_bin_edges
提供的算法之一计算箱子数量时,这种情况得以避免.
(gh-12150)
ndarray
的 shape-type 参数现在是协变的,并且绑定到 tuple[int, ...]
#
ndarray
的静态类型是一个长期的努力,随着这次改变继续进行.它是一个带有形状和数据类型参数的通用类型.以前,形状类型参数可以是任何值.这次改变将其限制为 int 的元组,正如使用 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版本开始,PEP 484类型注解已包含在 numpy.polynomial
及其子包中的函数和便利类中.
(gh-26897)
改进的 numpy.dtypes
类型提示#
numpy.dtypes
的类型注解现在更好地反映了运行时:numpy.dtype
类型别名已被专门的 dtype
子类型 取代,并且之前缺失的 numpy.dtypes.StringDType
的注解已被添加.
(gh-27008)
性能提升和变化#
numpy.save
现在使用 pickle 协议版本 4 来保存对象类型的数组,这允许保存大于 4GB 的 pickle 对象,并且对于大型数组,保存速度提高了约 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
现在不会对整数和布尔类型输入数组执行浮点类型的转换.(gh-26766)
ma.corrcoef
可能会返回一个略有不同的结果#
目前,在 ma.corrcoef
中使用成对观察方法来计算每对变量的标准差.这一做法已被更改,因为它被用于标准化使用 ma.cov
估计的协方差,而 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")
会引发 OverflowError 而不是 TypeError,因为同类型转换.np.copyto(float32_arr, 1e300, casting="safe")
会溢出到inf``(float32 无法容纳 ``1e300
)而不是引发 TypeError.
此外,在分配 NumPy 标量(或 0-d 数组)时,仅使用 dtype,这意味着以下行为有所不同:
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)