NumPy 1.21.0 版本说明#

NumPy 1.21.0 版本的亮点包括:

  • 继续进行 SIMD 工作,涵盖更多函数和平台;

  • 新的 dtype 基础架构和类型转换的初步工作;

  • 适用于 Mac 上 Python 3.8 和 Python 3.9 的 universal2 wheel 包;

  • 改进的文档;

  • 改进的注释;

  • 新的 PCG64DXSM 随机数生成器。

此外,还修复了大量错误并进行了其他改进。

此版本支持的 Python 版本为 3.7-3.9。Python 3.10 的官方支持将在其发布后添加。

警告

使用 gcc-11.1 编译 NumPy 1.20.0 时存在未解决的问题。

  • 优化级别 -O3 在运行测试时会导致许多不正确的警告。

  • 在某些硬件上,NumPy 会陷入无限循环。

新增函数#

添加了 PCG64DXSM BitGenerator#

在海量并行环境中使用 PCG64 BitGenerator 已被证明存在最初在 NumPy 1.17 版本中未发现的统计缺陷。大多数用户永远不会观察到此缺陷,并且可以安全地继续使用 PCG64。我们引入了一个新的 PCG64DXSM BitGenerator,它最终将成为未来版本中 default_rng 使用的新默认 BitGenerator 实现。PCG64DXSM 解决了统计缺陷,同时保留了 PCG64 的性能和特性。

有关更多详细信息,请参见 使用 PCG64DXSM 升级 PCG64

(gh-18906)

已过期的弃用#

  • shape 参数 unravel_index 不能再作为 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)

  • 已移除未使用的 PolyErrorPolyDomainError 异常。

    (gh-18963)

弃用#

.dtype 属性必须返回一个 dtype#

如果传递到 np.dtype 中的对象或作为 dtype=obj 参数的对象的 .dtype 属性不是 dtype,则现在会发出 DeprecationWarning 警告。NumPy 将停止尝试递归强制转换 .dtype 的结果。

(gh-13578)

numpy.convolvenumpy.correlate 的不精确匹配已弃用#

convolvecorrelate 现在在函数中找到对 mode 参数的大小写不敏感和/或不精确匹配时会发出警告。请传递完整的 "same""valid""full" 字符串,而不是 "s""v""f" 用于 mode 参数。

(gh-17492)

np.typeDict 已正式弃用#

np.typeDictnp.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)

已过期的弃用#

  • shape 参数 numpy.unravel_index 不能再作为 dims 关键字参数传递。(在 NumPy 1.16 中已弃用。)

    (gh-17900)

  • 函数 PyUFunc_GenericFunction 已被禁用。它在 NumPy 1.19 中已弃用。用户应直接使用 Python API 调用 ufunc。

    (gh-18697)

  • 函数 PyUFunc_SetUsesArraysAsData 已被禁用。它在 NumPy 1.19 中已弃用。

    (gh-18697)

移除已弃用的 PolyBase 和未使用的 PolyErrorPolyDomainError#

PolyBase 已被移除(在 NumPy 1.9.0 中已弃用)。请改用抽象类 ABCPolyBase

此外,未使用的 PolyErrorPolyDomainError 异常已从 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`,则生成的 value 为`high + (low - high) * random()`。

(gh-17921)

从默认包含路径中删除`/usr/include`#

使用`numpy.distutils`构建包时的默认包含路径不再包含`/usr/include`。此路径通常由编译器添加,对其进行硬编码可能会出现问题。如果这导致问题,请打开一个 issue。PR 18658 中记录了解决方法。

(gh-18658)

使用`dtype=...`的比较更改#

将来,比较ufunc(`equal`、`less`等)的`dtype=`(或`signature`)参数将表示所需的输出dtype。这意味着

`np.equal(2, 3, dtype=object)`

将发出`FutureWarning`警告,表明它将来会返回一个`object`数组,目前这种情况发生在

`np.equal(None, None, dtype=object)`

因为`np.array(None)`已经是一个对象数组。(这也发生在其他一些dtype上。)

由于比较通常只返回布尔数组,因此将来提供任何其他dtype都将始终引发错误,现在将给出`DeprecationWarning`警告。

(gh-18718)

ufunc中`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=`泛化和`casting`#

由于提升方面的更改,与1.20相比,1.21中`np.ufunc(1.0, 1.0, signature=...)`或`np.ufunc(1.0, 1.0, dtype=...)`的行为现在可能会产生不同的循环。以前使用`signature`时,对输入的强制转换检查比较宽松,这可能会导致不安全地向下转换输入,特别是如果与`casting="unsafe"`结合使用时。

现在保证强制转换是安全的。如果仅部分提供签名,例如使用`signature=("float64", None, None)`,这可能导致找不到循环(错误)。在这种情况下,有必要提供完整的签名以强制转换输入。如果使用`dtype="float64"`或仅设置输出(例如`signature=(None, None, "float64")`),则保持不变。我们预计受此更改影响的用户很少。

此外,`dtype="float64"`的含义略有修改,现在严格只强制执行正确的输出(而不是输入)DType。这意味着它现在始终等效于

signature=(None, None, "float64")

(如果ufunc有两个输入和一个输出)。由于这在某些情况下可能导致找不到循环,因此 NumPy 通常也会搜索循环

signature=("float64", "float64", "float64")

如果第一次搜索失败。将来,可以自定义此行为以实现更复杂的ufunc的预期结果。(对于某些通用函数,例如`np.ldexp`,输入可以具有不同的DType。)

(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)

新特性#

添加了一个mypy插件,用于处理特定于平台的`numpy.number`精度#

现在可以使用一个mypy插件来自动分配某些number子类的(特定于平台的)精度,包括int_intplonglong等。有关受影响类的全面概述,请参阅有关标量类型的文档。

请注意,虽然插件的使用完全是可选的,但如果没有它,上述类的精度将被推断为Any

要启用该插件,必须将其添加到 mypy 的配置文件中。

[mypy]
plugins = numpy.typing.mypy_plugin

(gh-17843)

让mypy插件管理扩展精度`numpy.number`子类#

numpy/numpy#17843中引入的mypy插件已扩展:该插件现在会删除对特定于平台的扩展精度类型(目标平台上不可用)的注释。例如,如果不可用,它将删除float128

如果没有插件,就 mypy 而言,_所有_扩展精度类型都将在所有平台上可用。

要启用该插件,必须将其添加到 mypy 的配置文件中。

[mypy]
plugins = numpy.typing.mypy_plugin

(gh-18322)

打印浮点值的新 min_digits 参数#

一个新的 min_digits 参数已添加到 dragon4 浮点打印函数 format_float_positionalformat_float_scientific。此关键字参数保证在 unique=True 模式下打印时,至少会打印指定数量的位数,即使额外的位数对于唯一指定值是不必要的。它是 precision 参数的对应参数,precision 参数设置要打印的位数的最大值。当在固定精度模式下 unique=False 时,它没有效果,并且 precision 参数决定位数。

(gh-18629)

f2py 现在识别 Fortran 抽象接口块#

f2py 现在可以解析抽象接口块。

(gh-18695)

通过环境变量配置 BLAS 和 LAPACK#

可以使用 NPY_BLAS_LIBSNPY_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截至 1.21 版本,NumPy 不支持注释数组形状,但这预计将在未来发生变化(参见 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 值都被认为是等效的(无论 NaN 位于实部还是虚部)。作为返回数组的代表,选择字典序中最小的那个 - 有关如何为复数数组定义字典序,请参见 np.sort

(gh-18070)

Generator.rayleighGenerator.geometric 性能提升#

Generator 中瑞利分布和几何分布随机变量生成的性能得到了提升。这两个都是指数随机变量的变换,并且慢速的基于对数的逆 cdf 变换已被基于 Ziggurat 的指数变量生成器取代。

当生成来自这两种分布的变量时,此更改会破坏生成的变量流。

(gh-18666)

占位符注释已改进#

所有以前注释为 typing.Any 的占位符注释都已改进。在适当的情况下,它们已被替换为显式函数定义、类或其他杂项对象。

(gh-18934)

性能改进#

NumPy 数组整数除法的性能提升#

当除数为常数时,NumPy 数组的整数除法现在使用 libdivide。通过使用 libdivide 和其他一些小的优化,速度得到了大幅提升。// 运算符和 np.floor_divide 使用了这些新的更改。

(gh-17727)

提高 np.savenp.load 对小数组的性能#

np.save 现在对小数组的速度快得多。

np.load 对小数组的速度也更快,但仅当使用版本 >= (3, 0) 进行序列化时。

这两种方法都是通过移除仅与 Python 2 相关的检查来完成的,同时仍然保持与可能由 Python 2 创建的数组的兼容性。

(gh-18657)

更改#

numpy.piecewise 输出类现在与输入类匹配#

当在 piecewise 的输入中使用 ndarray 子类时,它们会被传递给函数。输出现在也将会是与输入相同的子类。

(gh-18110)

启用 Accelerate 框架#

随着 macOS 11.3 的发布,numpy 在使用 Accelerate 框架的 BLAS 和 LAPACK 实现时遇到的几个问题应该都已解决。此更改使 Accelerate 框架成为 macOS 上的一个选项。如果发现其他问题,请使用开发者反馈助手工具 (https://developer.apple.com/bug-reporting/) 向 Accelerate 提交错误报告。我们打算迅速解决问题,并计划继续支持和更新我们的 BLAS 和 LAPACK 库。

(gh-18874)