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 中删除了许多 shims#
npy_3kcompat.h 中已移除许多旧的垫片程序和辅助函数.如果您发现自己需要这些,请将该文件之前的版本移植到您的代码库中.
( gh-26842 )
新的 PyUFuncObject 字段 process_core_dims_func#
字段 process_core_dims_func 已添加到结构体 PyUFuncObject .对于广义 ufunc,此字段可以设置为 PyUFunc_ProcessCoreDimsFunc 类型的函数,该函数将在调用 ufunc 时被调用.它允许 ufunc 作者检查核心维度是否满足其他约束,并在未提供输出核心维度大小时设置它们.
( gh-26908 )
新特性#
CPython 3.13 的初步自由线程支持#
CPython 3.13 将作为实验性的自由线程构建版本提供.有关自由线程 Python 的更多详细信息,请参见 https://py-free-threading.github.io, PEP 703 以及 CPython 3.13 release notes .
NumPy 2.1 提供了对 CPython 3.13 自由线程构建的初步支持. 此支持通过修复 NumPy 中的许多 C 线程安全问题来实现. 在 NumPy 2.1 之前,NumPy 使用了大量的 C 全局静态变量来存储运行时缓存和其他状态. 我们已经重构为避免对全局状态的需求,将全局状态转换为线程本地状态,或添加了锁定.
对自由线程 Python 的支持并不意味着 NumPy 是线程安全的. 对 ndarray 的只读共享访问应该是安全的. NumPy 公开了共享的可变状态,并且我们没有向数组对象本身添加任何锁定,以序列化对共享状态的访问. 如果您想在多个线程中改变同一个数组,则必须在用户代码中注意避免竞争. 通过在多个线程中同时改变一个数组,肯定有可能使 NumPy 崩溃,例如同时调用 ufunc 和 resize 方法. 目前,我们的指导是:“不要那样做”. 将来,我们希望提供更强的保证.
特别是对象数组需要特别注意,因为 GIL 以前为对象数组访问提供了锁定,但现在不再提供. 有关自由线程构建中的对象数组的更多信息,请参见 Issue #27199 .
如果您对自由线程 Python 感兴趣,例如因为您有一个基于多处理的工作流程,并且您有兴趣使用 Python 线程运行它,我们鼓励进行测试和实验.
如果您遇到您怀疑是由于 NumPy 引起的问题,请 open an issue ,首先检查该错误是否也发生在“常规”非自由线程 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为 1).( 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 的静态类型提示是一项长期工作,此更改将继续. 它是具有形状和数据类型类型参数的泛型类型. 以前,形状类型参数可以是任何值. 此更改将其限制为一个整数元组,正如人们期望从使用 ndarray.shape 中获得的一样. 此外,形状类型参数已从不变更改为协变. 此更改也适用于 ndarray 的子类型,例如 numpy.ma.MaskedArray . 更多信息请参阅 typing docs .
( gh-26081 )
带有方法 closest_observation 的 np.quantile 选择最接近的偶数阶统计量#
这会将边界情况下最近邻的定义从最近的奇数阶统计量更改为最近的偶数阶统计量. numpy 实现现在与其他参考实现匹配.
( gh-26656 )
lapack_lite 现在是线程安全的#
如果在构建时未检测到 BLAS/LAPACK 系统,NumPy 提供了一个名为 lapack_lite 的最小的低性能 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 来保存带有 object 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 输入数组执行到浮点 dtype 的转换.( 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 维数组)时使用 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 )