NumPy 1.21.0 Release Notes#
NumPy 1.21.0 版本的主要亮点包括:
持续的 SIMD 工作,涵盖更多函数和平台;
新的 dtype 基础设施和转换的初步工作;
Mac 上的 Python 3.8 和 Python 3.9 的 universal2 wheels;
改进的文档;
改进的注解;
用于随机数的新
PCG64DXSMbitgenerator。
此外,还有一如既往的大量错误修复和其他改进。
此版本支持的 Python 版本为 3.7-3.9。Python 3.10 正式发布后将增加官方支持。
警告
使用 gcc-11.1 编译 NumPy 1.20.0 时存在未解决的问题。
优化级别 -O3 在运行测试时会导致许多不正确的警告。
在某些硬件上,NumPY 会挂起在无限循环中。
新增函数#
添加 PCG64DXSM BitGenerator#
在 NumPy 1.17 发布时,PCG64 BitGenerator 在大规模并行环境中的使用被证明存在统计上的弱点,这些弱点在首次发布时并不明显。大多数用户将永远不会遇到这种弱点,并且可以继续安全地使用 PCG64。我们引入了一个新的 PCG64DXSM BitGenerator,它最终将在未来的版本中成为 default_rng 使用的新默认 BitGenerator 实现。PCG64DXSM 解决了统计弱点,同时保留了 PCG64 的性能和特性。
有关更多详细信息,请参阅 使用 PCG64DXSM 升级 PCG64。
(gh-18906)
已过期的弃用#
unravel_index的shape参数不再可以作为dims关键字参数传递。(已在 NumPy 1.16 中弃用。)(gh-17900)
函数
PyUFunc_GenericFunction已被禁用。它在 NumPy 1.19 中已被弃用。用户应通过 Python API 直接调用 ufunc。(gh-18697)
函数
PyUFunc_SetUsesArraysAsData已被禁用。它在 NumPy 1.19 中已被弃用。(gh-18697)
类
PolyBase已被移除(在 numpy 1.9.0 中已弃用)。请改用抽象类ABCPolyBase。(gh-18963)
已移除未使用的
PolyError和PolyDomainError异常。(gh-18963)
弃用#
`.dtype` 属性必须返回一个 `dtype`#
如果传递到 `np.dtype` 或作为 `dtype=obj` 参数的对象,其 `.dtype` 属性不是 dtype,现在会发出 `DeprecationWarning`。NumPy 将停止尝试递归转换 `.dtype` 的结果。
(gh-13578)
`numpy.convolve` 和 `numpy.correlate` 的不精确匹配已弃用#
`convolve` 和 `correlate` 现在会在函数中为 `mode` 参数找到不区分大小写和/或不精确匹配时发出警告。请为 `mode` 参数传递完整的 `"same"`、`"valid"`、`"full"` 字符串,而不是 `"s"`、`"v"`、`"f"`。
(gh-17492)
`np.typeDict` 已被正式弃用#
`np.typeDict` 是 `np.sctypeDict` 的一个已弃用别名,并且已经存在了超过 14 年(6689502)。现在每次访问 `np.typeDict` 时都会发出弃用警告。
(gh-17586)
在类数组创建期间将引发异常#
当对象在访问特殊属性 `__array__` 或 `__array_interface__` 时引发异常,该异常通常会被忽略。现在当异常不是 AttributeError 时会发出警告。要抑制警告,必须修改引发异常的类型,使其引发 `AttributeError`。
(gh-19001)
四个 `ndarray.ctypes` 方法已被弃用#
`ndarray.ctypes` 对象的四个方法已被弃用,因为它们是其各自属性(未文档化)的实现产物。
相关方法为:
`_ctypes.get_data`(使用 `_ctypes.data` 代替)
`_ctypes.get_shape`(使用 `_ctypes.shape` 代替)
`_ctypes.get_strides`(使用 `_ctypes.strides` 代替)
`_ctypes.get_as_parameter`(使用 `_ctypes._as_parameter_` 代替)
(gh-19031)
过期的弃用#
`numpy.unravel_index` 的 `shape` 参数不再可以作为 `dims` 关键字参数传递。(已在 NumPy 1.16 中弃用。)
(gh-17900)
函数
PyUFunc_GenericFunction已被禁用。它在 NumPy 1.19 中已被弃用。用户应通过 Python API 直接调用 ufunc。(gh-18697)
函数
PyUFunc_SetUsesArraysAsData已被禁用。它在 NumPy 1.19 中已被弃用。(gh-18697)
移除弃用的 `PolyBase` 和未使用的 `PolyError` 及 `PolyDomainError`#
类 PolyBase 已被移除(在 numpy 1.9.0 中已弃用)。请改用抽象类 ABCPolyBase。
此外,未使用的 `PolyError` 和 `PolyDomainError` 异常已从 `numpy.polynomial` 中移除。
(gh-18963)
兼容性说明#
通用函数中的错误类型更改#
在某些情况下,通用函数现在可能对无效输入引发不同的错误。主要变化是将 `RuntimeError` 替换为更合适的 `TypeError`。当同一调用中存在多个错误时,NumPy 现在可能引发一个不同的错误。
(gh-15271)
`__array_ufunc__` 参数验证#
NumPy 现在将在调用 `__array_ufunc__` 之前部分验证参数。以前,当已知会发生调度时,可以传递无效参数(例如,不存在的关键字参数)。
(gh-15271)
`__array_ufunc__` 和其他位置参数#
以前,所有通过位置传递的参数都会被检查是否支持 `__array_ufunc__`。对于 `reduce`、`accumulate` 和 `reduceat`,所有参数都可以通过位置传递。这意味着当它们通过位置传递时,以前可以要求它们通过 `__array_ufunc__` 处理 ufunc 调用。由于这取决于参数传递方式(通过位置或通过关键字),NumPy 现在仅根据输入和输出数组进行调度。例如,NumPy 在 `np.add.reduce` 这样的归约中,永远不会根据 `where` 数组进行调度。
(gh-15271)
验证 `Generator.uniform` 中的输入值#
在 `np.random.Generator.uniform` 中检查了 `high - low >= 0`。如果 `low > high`,则引发 `ValueError`。以前,顺序颠倒的输入是可以接受的,并且会被静默交换,因此如果 `low > high`,生成的值为 `high + (low - high) * random()`。
(gh-17921)
从默认包含路径中移除了 `/usr/include`#
使用 `numpy.distutils` 构建包时,默认的包含路径不再包含 `/usr/include`。此路径通常由编译器添加,硬编码可能会有问题。如果这导致问题,请提交一个 issue。PR 18658 中记录了一个解决方法。
(gh-18658)
与 `dtype=...` 的比较更改#
当使用比较 ufuncs(`equal`、`less` 等)的 `dtype=`(或 `signature`)参数时,将来这会表示所需的输出 dtype。这意味着
np.equal(2, 3, dtype=object)
将发出 `FutureWarning`,表示将来会返回一个 `object` 数组,而目前这对于
np.equal(None, None, dtype=object)
由于 `np.array(None)` 已经是 object 数组。(对于某些其他 dtype 也会发生这种情况。)
由于比较通常只返回布尔数组,将来提供任何其他 dtype 都将始终引发错误,而现在则会发出 `DeprecationWarning`。
(gh-18718)
ufuncs 中 `dtype` 和 `signature` 参数的更改#
通用函数参数 `dtype` 和 `signature`(对于归约如 `np.add.reduce`(即 `np.sum` 的实现)也有效)现在将在提供的 `dtype` 不是“基本” dtype 时发出警告。
NumPy 几乎总是忽略这些输入的元数据、字节序或时间单位。NumPy 现在将始终忽略它们,并在字节序或时间单位发生更改时引发错误。以下是会引发错误的最重要示例。在某些情况下,之前存储的信息并未被忽略,在所有这些情况下,现在都会引发错误。
# Previously ignored the byte-order (affect if non-native)
np.add(3, 5, dtype=">i32")
# The biggest impact is for timedelta or datetimes:
arr = np.arange(10, dtype="m8[s]")
# The examples always ignored the time unit "ns":
np.add(arr, arr, dtype="m8[ns]")
np.maximum.reduce(arr, dtype="m8[ns]")
# The following previously did use "ns" (as opposed to `arr.dtype`)
np.add(3, 5, dtype="m8[ns]") # Now return generic time units
np.maximum(arr, arr, dtype="m8[ns]") # Now returns "s" (from `arr`)
对于像 `np.sum` 这样在内部使用这些函数的函数也适用。此更改对于实现 NumPy 内部的一致处理是必需的。
如果遇到这些问题,在大多数情况下,请例如传递 `dtype=np.timedelta64`,这清楚地表示了一个没有定义单位或字节序的通用 `timedelta64`。如果您需要精确指定输出 dtype,可以通过转换输入或使用 `out=` 提供输出数组来完成。
NumPy 将来可能会允许在此处提供精确的输出 `dtype`,届时将发出 `FutureWarning`。
(gh-18718)
ufunc `signature=...` 和 `dtype=...` 的泛化和类型转换#
由于 1.21 中由于类型提升的变化,`np.ufunc(1.0, 1.0, signature=...)` 或 `np.ufunc(1.0, 1.0, dtype=...)` 的行为可能与 1.20 不同。以前使用 `signature` 时,对输入的类型转换检查会放宽,这可能导致不安全地向下转换输入,特别是与 `casting="unsafe"` 结合使用时。
类型转换现在保证是安全的。如果 `signature` 只提供了部分信息,例如使用 `signature=("float64", None, None)`,这可能导致找不到循环(出错)。在这种情况下,必须提供完整的 `signature` 来强制转换输入。如果使用 `dtype="float64"` 或仅设置输出(例如 `signature=(None, None, "float64")`),则不会发生变化。我们预计只有很少的用户会受到此更改的影响。
此外,`dtype="float64"` 的含义略有修改,现在仅严格强制正确的输出(而非输入) DType。这意味着它现在始终等同于
signature=(None, None, "float64")
(如果 ufunc 有两个输入和一个输出)。由于这可能导致在某些情况下找不到循环,NumPy 通常还会搜索循环
signature=("float64", "float64", "float64")
如果第一次搜索失败。将来,此行为可能会根据需要进行自定义,以实现更复杂 ufuncs 的预期结果。(对于某些通用函数,例如 `np.ldexp`,输入可以具有不同的 DTypes。)
(gh-18880)
Distutils 对 clang 强制执行严格浮点模型#
使用 clang 编译时,NumPy distutils 现在将始终添加 `-ffp-exception-behavior=strict` 编译器标志。Clang 默认使用非严格版本,这允许编译器生成不正确设置浮点警告/错误的代码。
(gh-19049)
C API 更改#
使用 `ufunc->type_resolver` 和“类型元组”#
NumPy 现在在调用类型解析函数之前会规范化“类型元组”参数。请注意,使用此类型解析器是遗留行为,NumPy 在可能的情况下不会这样做。强烈不建议调用 `ufunc->type_resolver` 或 `PyUFunc_DefaultTypeResolver`,现在如果这样做,将强制执行规范化的类型元组。请注意,这不会影响提供类型解析器,在大多数情况下,类型解析器应该仍然有效。如果您有意外的调用类型解析器的用例,请告知 NumPy 开发人员,以便找到解决方案。
(gh-18718)
新功能#
为处理平台特定的 `numpy.number` 精度添加了 mypy 插件#
现在提供了一个 mypy 插件,用于自动分配某些 `numpy.number` 子类的(平台相关的)精度,包括 `int_`、`intp` 和 `longlong` 等。有关受影响类的全面概述,请参阅关于 标量类型 的文档。
请注意,虽然使用该插件是完全可选的,但如果没有它,上述类的精度将推断为 Any。
要启用该插件,必须将其添加到 mypy 的 配置文件中。
[mypy]
plugins = numpy.typing.mypy_plugin
(gh-17843)
让 mypy 插件管理扩展精度 `numpy.number` 子类#
在 numpy/numpy#17843 中引入的 mypy 插件已得到扩展:该插件现在会移除平台上不可用的平台特定扩展精度类型的注解。例如,当 `float128` 不可用时,它会移除 `float128` 的注解。
在没有插件的情况下,就 mypy 而言,所有扩展精度类型都将在所有平台上可用。
要启用该插件,必须将其添加到 mypy 的 配置文件中。
[mypy]
plugins = numpy.typing.mypy_plugin
(gh-18322)
用于打印浮点值的新 `min_digits` 参数#
在 dragon4 浮点打印函数 `format_float_positional` 和 `format_float_scientific` 中添加了一个新的 `min_digits` 参数。当在 `unique=True` 模式下打印时,此关键字参数保证至少会打印给定的位数,即使额外的位数不是唯一指定值所必需的。它是 `precision` 参数的对应项,`precision` 参数设置要打印的最大位数。当 `unique=False` 且处于固定精度模式时,它没有影响,`precision` 参数固定了打印的位数。
(gh-18629)
f2py 现在可以识别 Fortran 抽象接口块#
f2py 现在可以解析抽象接口块。
(gh-18695)
通过环境变量配置 BLAS 和 LAPACK#
可以通过使用 `NPY_BLAS_LIBS` 和 `NPY_LAPACK_LIBS` 环境变量来绕过已安装 BLAS 和 LAPACK 库的自动检测。相反,将直接使用这些环境变量中的链接标志,并且假定语言为 F77。这对于自动化构建尤其有用,因为已安装的 BLAS 和 LAPACK 是精确已知的。一个用例是通过存根库链接在运行时替换实际实现。
如果设置了 `NPY_CBLAS_LIBS`(可选,除了 `NPY_BLAS_LIBS`),它也将被使用,通过定义 `HAVE_CBLAS` 并将环境变量内容附加到链接标志。
(gh-18737)
为 `ndarray` 添加了一个运行时可下标的别名#
`numpy.typing.NDArray` 已被添加,它是 `np.ndarray[Any, np.dtype[~Scalar]]` 的运行时可下标别名。新的类型别名可用于注释具有给定 dtype 和未指定形状的数组。1
1 NumPy 在 1.21 版本中不支持数组形状的注解,未来预计会发生变化(参见 PEP 646)。
示例#
>>> import numpy as np
>>> import numpy.typing as npt
>>> print(npt.NDArray)
numpy.ndarray[typing.Any, numpy.dtype[~ScalarType]]
>>> print(npt.NDArray[np.float64])
numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
>>> NDArrayInt = npt.NDArray[np.int_]
>>> a: NDArrayInt = np.arange(10)
>>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
... return np.array(a)
(gh-18935)
改进#
`numpy.unwrap` 的任意 `period` 选项#
解相位间隔的大小不再限于 `2 * pi`。这对于解相位(例如角度)尤其有用,但也可用于其他区间。
>>> phase_deg = np.mod(np.linspace(0,720,19), 360) - 180
>>> phase_deg
array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
-180., -140., -100., -60., -20., 20., 60., 100., 140.,
-180.])
>>> unwrap(phase_deg, period=360)
array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
180., 220., 260., 300., 340., 380., 420., 460., 500.,
540.])
(gh-16987)
`np.unique` 现在返回单个 `NaN`#
当 `np.unique` 操作包含多个 `NaN` 条目的数组时,其返回值会包含每个对应于原始数组中 `NaN` 的条目。现在已改进此行为,返回的数组只包含一个 `NaN` 作为最后一个元素。
对于复数数组,所有 `NaN` 值都被视为等效(无论 `NaN` 是在实部还是虚部)。作为返回数组的代表,选择词典顺序中最小的那个 - 请参阅 `np.sort` 以了解复数数组的词典顺序定义。
(gh-18070)
`Generator.rayleigh` 和 `Generator.geometric` 性能提升#
Rayleigh 和 geometric 随机变数生成在 `Generator` 中的性能有所提高。这些都是指数随机变量的变换,基于 log 的慢速逆 cdf 变换已被替换为基于 Ziggurat 的指数变数生成器。
此更改会破坏从这些分布中生成变数时的变数流。
(gh-18666)
占位符注解已得到改进#
所有先前被注解为 `typing.Any` 的占位符注解都已得到改进。在适当的情况下,它们已被替换为显式的函数定义、类或其他杂项对象。
(gh-18934)
性能改进#
NumPy 数组整数除法的性能提升#
当除数是常量时,NumPy 数组的整数除法现在使用 libdivide。通过使用 libdivide 和其他小优化,速度有了很大提升。`//` 运算符和 `np.floor_divide` 利用了这些新变化。
(gh-17727)
针对小数组的 `np.save` 和 `np.load` 性能提升#
对于小数组,`np.save` 现在速度快了很多。
np.load 在序列化版本 >= 3.0 时,对小型数组也更快。
这两种方法都是通过移除仅与 Python 2 相关的检查来实现的,同时仍能与可能由 Python 2 创建的数组保持兼容。
(gh-18657)
更改#
numpy.piecewise 的输出类现在与输入类匹配#
当 ndarray 子类用作 piecewise 的输入时,它们会被传递给函数。现在输出也将是相同的子类。
(gh-18110)
启用 Accelerate Framework#
随着 macOS 11.3 的发布,numpy 在使用 Accelerate Framework 的 BLAS 和 LAPACK 实现时遇到的一些问题应该已经得到解决。此更改将 Accelerate Framework 作为一个选项在 macOS 上启用。如果发现其他问题,请使用开发者反馈助手工具 (https://developer.apple.com/bug-reporting/) 针对 Accelerate 提交 bug 报告。我们打算及时解决问题,并计划继续支持和更新我们的 BLAS 和 LAPACK 库。
(gh-18874)