NumPy 1.21.0 发行说明#

NumPy 1.21.0 版本的亮点包括

  • 持续的 SIMD 工作,涵盖更多函数和平台,

  • 新的 dtype 基础设施和类型转换的初始工作,

  • 适用于 Mac 上 Python 3.8 和 Python 3.9 的 universal2 wheels,

  • 改进的文档,

  • 改进的注解,

  • 用于随机数的新 PCG64DXSM bitgenerator.

此外,还有大量常见的错误修复和其他改进.

此版本支持的 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__ 和额外的 positional 参数#

之前,所有通过位置传递的参数都会检查是否支持 __array_ufunc__ .对于 reduce , accumulatereduceat ,所有参数都可以按位置传递.这意味着当它们按位置传递时,它们以前可能已被要求通过 __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=... 的比较的更改#

当比较 ufunc( 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 )

dtypesignature 参数在 ufunc 中的更改#

通用函数参数 dtypesignature 对归约 (reduction) 也有效,例如 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,你可以通过 casting 输入或使用 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 不同的 loops.当先前使用 signature 时,inputs 上的选型检查被放宽,这可能导致不安全地向下转换输入,特别是与 casting="unsafe" 组合使用时.

现在保证了 Casting 是安全的.如果只部分提供一个 signature,例如使用 signature=("float64", None, None) ,这可能会导致找不到 loop(一个错误).在这种情况下,有必要提供完整的 signature 来强制转换输入.如果使用 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_resolverPyUFunc_DefaultTypeResolver ,如果这样做,现在将强制执行规范化的类型元组. 请注意,这不会影响提供类型解析器,预计在大多数情况下都可以正常工作. 如果您对调用类型解析器有未预期的用例,请告知 NumPy 开发人员,以便找到解决方案.

( gh-18718 )

新特性#

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

现在可以使用 mypy 插件来自动分配某些 number 子类的(平台相关的)精度,包括 int_ , intplonglong 等. 有关受影响类的全面概述,请参阅 scalar types 上的文档.

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

要启用该插件,必须将其添加到他们的 mypy configuration file 中:

[mypy]
plugins = numpy.typing.mypy_plugin

( gh-17843 )

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

numpy/numpy#17843 中引入的 mypy 插件已得到扩展:现在,该插件会删除不可用于相关平台的平台特定扩展精度类型的注解. 例如,它将删除 float128 (如果不可用).

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

要启用该插件,必须将其添加到他们的 mypy configuration file 中:

[mypy]
plugins = numpy.typing.mypy_plugin

( gh-18322 )

用于打印浮点值的新 min_digits 参数#

已将新的 min_digits 参数添加到 dragon4 浮点打印函数 format_float_positionalformat_float_scientific .此 kword 保证在 unique=True 模式下打印时,至少会打印给定的位数,即使额外的位数对于唯一指定该值是不必要的.它是 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 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 值都被认为是等效的(无论 NaN 在实部还是虚部中).作为返回数组的代表,选择字典顺序中最小的一个 - 有关复数数组的字典顺序的定义,请参见 np.sort .

( gh-18070 )

Generator.rayleighGenerator.geometric 的性能得到提高#

Generator 中瑞利分布和几何分布随机变量生成的性能得到了提高.这些都是指数随机变量的转换,并且基于log的反函数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 Framework#

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

( gh-18874 )