NumPy 1.21.0 发布说明#

NumPy 1.21.0 版本亮点是

  • 继续 SIMD 工作,涵盖更多功能和平台,

  • 对新的 dtype 基础设施和转换的初步工作

  • 适用于 Mac 上 Python 3.8 和 Python 3.9 的 universal2 轮子

  • 改进的文档

  • 改进的注解

  • 新的 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 属性或作为 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.

此外,`numpy.polynomial` 中未使用的 PolyErrorPolyDomainError 异常被移除.

(gh-18963)

兼容性说明#

通用函数中的错误类型变化#

在某些情况下,通用函数现在可能会在无效输入时引发不同的错误.主要的变化应该是 RuntimeError 被更合适的 TypeError 取代.当同一调用中存在多个错误时,NumPy 现在可能会引发不同的错误.

(gh-15271)

__array_ufunc__ 参数验证#

NumPy 现在将在调用 __array_ufunc__ 之前部分验证参数.以前,当已知会发生调度时,可以传递无效参数(例如不存在的关键字参数).

(gh-15271)

__array_ufunc__ 和额外的位置参数#

之前,所有按位置传递的参数都会被检查是否支持 __array_ufunc__.在 reduceaccumulatereduceat 的情况下,所有参数都可以按位置传递.这意味着当它们按位置传递时,它们之前可能被要求通过 __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.这个路径通常由编译器添加,硬编码它可能会引起问题.如果这导致了问题,请打开一个问题.在 PR 18658 中有记录一个解决方案.

(gh-18658)

dtype=... 的比较的更改#

当比较ufuncs(如 equalless 等)使用 dtype=``(或 ``signature)参数时,这将表示未来所需的输出数据类型.这意味着:

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

将给出 FutureWarning ,表示它将来会返回一个 object 数组,这在当前情况下会发生:

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

由于 np.array(None) 已经是一个对象数组.(对于某些其他数据类型也会发生这种情况.)

由于比较通常只返回布尔数组,提供任何其他数据类型将来总会引发错误,现在会给出 DeprecationWarning.

(gh-18718)

对 ufuncs 中的 dtypesignature 参数的更改#

通用函数参数 dtypesignature 对于诸如 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#

np.ufunc(1.0, 1.0, signature=...)np.ufunc(1.0, 1.0, dtype=...) 的行为在 1.21 版本中可能与 1.20 版本产生不同的循环,这是由于提升机制的变化.当之前使用 signature 时,输入的类型转换检查被放宽,这可能导致不安全的输入降级,尤其是在结合 casting="unsafe" 使用时.

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

此外,``dtype=”float64”`` 的含义已经稍微修改,现在严格只强制正确的输出(而不是输入)DTypes.这意味着它现在总是等同于:

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_resolverPyUFunc_DefaultTypeResolver,如果这样做,现在会强制执行一个规范化的类型元组.请注意,这不会影响提供类型解析器,预计在大多数情况下仍能正常工作.如果您有调用类型解析器的意外用例,请告知 NumPy 开发者,以便找到解决方案.

(gh-18718)

新功能#

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

现在有一个 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 模式下打印时至少会打印给定的位数,即使额外的位数对于唯一指定值是不必要的.它是设置打印最大位数的精度参数的对应物.当在固定精度模式下 unique=False 时,它没有效果,并且精度参数固定了位数.

(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 是在实部还是虚部).作为返回数组的代表,选择字典序中最小的那个 - 见 np.sort 了解如何为复杂数组定义字典序.

(gh-18070)

Generator.rayleighGenerator.geometric 性能提升#

Generator 中 Rayleigh 和几何随机变量生成的性能得到了提升.这两种方法都是指数随机变量的变换,基于对数逆累积分布函数(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 输出类现在匹配输入类#

ndarray 子类在输入到 piecewise 时使用,它们会被传递给函数.输出也将是相同的子类.

(gh-18110)

启用加速框架#

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

(gh-18874)