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 变更#
许多 shim 已从 npy_3kcompat.h 中移除#
许多旧的 shim 和辅助函数已从 npy_3kcompat.h 中移除.如果您发现自己需要这些,请将该文件的先前版本 vendor 到您的代码库中.
( 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 的静态类型是一个长期的工作,这项更改将继续进行. 它是具有形状和数据类型的类型参数的泛型类型. 以前,shape type 参数可以是任何值. 此更改将其限制为整数元组,正如人们从使用 ndarray.shape 所期望的那样. 此外,shape-type 参数已从不变更改为协变. 此更改也适用于 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 估计的,后者不考虑成对变量的观察值,因此是不必要的. 归一化已替换为每个变量更合适的标准偏差,这显着减少了挂钟时间,但在变量对之间的观察值未对齐的情况下,将返回略有不同的相关系数估计值. 但是,它将在所有其他情况下返回相同的估计值,包括在使用没有屏蔽值的屏蔽数组时返回与 corrcoef 相同的相关矩阵.
( gh-26285 )
copyto 和 full 中的 Cast-safety 修复#
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 )