NumPy 1.24 发行说明#

NumPy 1.24.0 版本继续致力于改进 dtype 的处理和提升,提高执行速度,并阐明文档。由于促销和清理的变化,还有大量的新的和过期的弃用。这可以称为一个弃用版本。亮点是

  • 许多新的弃用,请查看。

  • 许多过期的弃用,

  • 新的 F2PY 功能和修复。

  • 堆叠函数新增“dtype”和“casting”关键字。

详情请见下文,

此版本支持 Python 3.8-3.11。

弃用#

弃用 fastCopyAndTranspose 和 PyArray_CopyAndTranspose#

已弃用 numpy.fastCopyAndTranspose 函数。请直接使用相应的 copy 和 transpose 方法。

arr.T.copy()

底层的 C 函数 PyArray_CopyAndTranspose 也已从 NumPy C-API 中弃用。

(gh-22313)

越界 Python 整数的转换#

将 Python 整数转换为 NumPy 值时,现在将始终检查结果是否能被 NumPy 表示。这意味着以下示例将来会失败,并且现在会发出 DeprecationWarning

np.uint8(-1)
np.array([3000], dtype=np.int8)

许多这些以前是成功的。此类代码主要对无符号整数(带有负值)有用,例如 np.uint8(-1),它会得到 np.iinfo(np.uint8).max

请注意,NumPy 整数之间的转换不受影响,因此 np.array(-1).astype(np.uint8) 将继续工作并使用 C 整数溢出逻辑。对于负值,查看数组也将起作用:np.array(-1, dtype=np.int8).view(np.uint8)。在某些情况下,使用 np.iinfo(np.uint8).maxval % 2**8 也可能有效。

在极少数情况下,输入数据可能同时包含负值和非常大的无符号值(例如 -12**63)。在这种情况下,不幸的是,需要对 Python 值使用 %,或者根据是否预期负值来使用有符号或无符号转换。

(gh-22385)

弃用 msort#

已弃用 numpy.msort 函数。请改用 np.sort(a, axis=0)

(gh-22456)

np.str0 及类似项现已弃用#

以 0 位大小结尾的标量类型别名:np.object0np.str0np.bytes0np.void0np.int0np.uint0 以及 np.bool8 现已弃用,并将最终被移除。

(gh-22607)

已过期的弃用#

  • 已从 np.histogramnp.histogram2dnp.histogramdd 中移除 normed 关键字参数。请改用 density。如果 normed 是按位置传递的,现在将使用 density

    (gh-21645)

  • 除非传递 dtype=object,否则现在创建不规则数组总是会引发 ValueError。这包括非常深嵌套的序列。

    (gh-22004)

  • 已移除对 Visual Studio 2015 及更早版本的支持。

  • 已移除对 Windows Interix POSIX 互操作层(interop layer)的支持。

    (gh-22139)

  • 已移除对 Cygwin < 3.3 的支持。

    (gh-22159)

  • 已移除 np.ma.MaskedArraymini() 方法。请使用 np.ma.MaskedArray.min()np.ma.minimum.reduce()

  • 已移除 np.ma.minimumnp.ma.maximum 的单参数形式。请改用 np.ma.minimum.reduce()np.ma.maximum.reduce()

    (gh-22228)

  • 向 ufuncs 中的 dtype=signature= 传递非规范(主要是本地字节序)的 dtype 实例现在将引发 TypeError。我们建议传递字符串 "int8" 或标量类型 np.int8,因为字节序、datetime/timedelta 单位等从未强制执行。(最初在 NumPy 1.21 中弃用。)

    (gh-22540)

  • 传递给比较 ufuncs 的 dtype= 参数现在已正确应用。这意味着只有 boolobject 是有效值,并且强制执行 dtype=object

    (gh-22541)

  • 别名 np.objectnp.boolnp.floatnp.complexnp.strnp.int 的弃用已过期(引入于 NumPy 1.20)。其中一些现在将发出 FutureWarning 并引发错误,因为它们将来将被映射到 NumPy 标量。

    (gh-22607)

兼容性说明#

array.fill(scalar) 的行为可能略有不同#

由于逻辑与项赋值对齐,numpy.ndarray.fill 在某些情况下现在的行为可能略有不同。

arr = np.array([1])  # with any dtype/value
arr.fill(scalar)
# is now identical to:
arr[0] = scalar

先前,在使用无法在目标 dtype 中表示的值时,或者当目标具有 object dtype 时,转换可能产生略微不同的结果。

(gh-20924)

子数组到对象(object)的转换现在进行复制#

将包含子数组的 dtype 转换为对象类型现在将确保复制子数组。先前返回了不安全的视图。

arr = np.ones(3, dtype=[("f", "i", 3)])
subarray_fields = arr.astype(object)[0]
subarray = subarray_fields[0]  # "f" field

np.may_share_memory(subarray, arr)

现在总是为 false。而之前对于特定的转换是 true。

(gh-21925)

返回的数组尊重 dtype 关键字参数对象的唯一性#

dtype 关键字参数与 arrayasarray 一起使用时,返回数组的 dtype 现在始终与调用者提供的 dtype 完全匹配。

在某些情况下,此更改意味着返回的是*视图*而不是输入数组。以下是关于 64 位 Linux 的一个示例,其中 longlonglong 精度相同但 dtypes 不同。

>>> arr = np.array([1, 2, 3], dtype="long")
>>> new_dtype = np.dtype("longlong")
>>> new = np.asarray(arr, dtype=new_dtype)
>>> new.dtype is new_dtype
True
>>> new is arr
False

在此更改之前,dtype 不匹配,因为 new is arrTrue

(gh-21995)

DLPack 导出引发 BufferError#

当数组缓冲区无法通过 DLPack 导出时,现在始终引发 BufferError,而以前会引发 TypeErrorRuntimeError。这允许在 DLPack 首先尝试时回退到 buffer 协议或 __array_interface__

(gh-22542)

不再在 GCC-6 上测试 NumPy 构建#

Ubuntu 18.04 已弃用 GitHub Actions,而 GCC-6 在 Ubuntu 20.04 上不可用,因此不再测试使用该编译器的构建。我们仍然测试使用 GCC-7 和 GCC-8 的构建。

(gh-22598)

新功能#

多项式类添加了新的 symbol 属性#

NumPy 的 numpy.polynomial 包中的多项式类新增了一个 symbol 属性,用于表示多项式的变量。打印时可用于更改变量的值。

>>> P_y = np.polynomial.Polynomial([1, 0, -1], symbol="y")
>>> print(P_y)
1.0 + 0.0·y¹ - 1.0·y²

请注意,多项式类仅支持一维多项式,因此当结果为多元时,不允许进行涉及具有不同变量的多项式运算。

>>> P = np.polynomial.Polynomial([1, -1])  # default symbol is "x"
>>> P_z = np.polynomial.Polynomial([1, 1], symbol="z")
>>> P * P_z
Traceback (most recent call last)
   ...
ValueError: Polynomial symbols differ

该变量可以是任何有效的 Python 标识符。默认值为 symbol=x,与现有行为一致。

(gh-16154)

F2PY 支持 Fortran character 字符串#

F2PY 现在支持封装 Fortran 函数,其参数为:

  • character(例如 character x

  • character 数组(例如 character, dimension(n) :: x

  • character 字符串(例如 character(len=10) x

  • 以及 character 字符串数组(例如 character(len=10), dimension(n, m) :: x

参数,包括将 Python Unicode 字符串作为 Fortran 字符字符串参数传递。

(gh-19388)

新函数 np.show_runtime#

新增了 numpy.show_runtime 函数,用于显示机器的运行时信息,此外还有 numpy.show_config,用于显示与构建相关的信息。

(gh-21468)

testing.assert_array_equalstrict 选项#

现在 testing.assert_array_equal 可用 strict 选项。将 strict=True 设置为 True 将禁用标量的广播行为,并确保输入数组具有相同的数据类型。

(gh-21595)

np.unique 添加了新参数 equal_nan#

np.unique 在 1.21 中被更改,将其视为所有 NaN 值相等,并返回一个 NaN。将 equal_nan=False 设置为 False 将恢复 1.21 之前的行为,即 NaN 被视为唯一。默认为 True

(gh-21623)

numpy.stackcastingdtype 关键字参数#

现在 numpy.stack 可用 castingdtype 关键字参数。要使用它们,请写 np.stack(..., dtype=None, casting='same_kind')

numpy.vstackcastingdtype 关键字参数#

现在 numpy.vstack 可用 castingdtype 关键字参数。要使用它们,请写 np.vstack(..., dtype=None, casting='same_kind')

numpy.hstackcastingdtype 关键字参数#

现在 numpy.hstack 可用 castingdtype 关键字参数。要使用它们,请写 np.hstack(..., dtype=None, casting='same_kind')

(gh-21627)

单例 RandomState 底层的位生成器(bit generator)可以被更改#

NumPy 模块中暴露的单例 RandomState 实例在启动时使用 MT19937 位生成器初始化。新的 set_bit_generator 函数允许用用户提供的位生成器替换默认的位生成器。引入此函数是为了提供一种方法,允许将高质量的现代位生成器无缝集成到新代码中,同时与使用单例提供的随机变量生成函数的现有代码兼容。伴随函数 get_bit_generator 返回单例 RandomState 当前使用的位生成器。这可以简化在需要时恢复原始随机源。

生成可重现随机数的首选方法是使用 Generator 实例中的现代位生成器。 default_rng 函数简化了实例化。

>>> rg = np.random.default_rng(3728973198)
>>> rg.random()

然后可以将相同的位生成器与单例实例共享,以便调用 random 模块中的函数将使用相同的位生成器。

>>> orig_bit_gen = np.random.get_bit_generator()
>>> np.random.set_bit_generator(rg.bit_generator)
>>> np.random.normal()

交换是永久性的(除非被撤销),因此任何对 random 模块中函数的调用都将使用新的位生成器。如果需要代码正确运行,可以恢复原始的位生成器。

>>> np.random.set_bit_generator(orig_bit_gen)

(gh-21976)

np.void 现在有一个 dtype 参数#

NumPy 现在允许通过将 dtype 参数传递给 np.void 来直接构造结构化 void 标量。

(gh-22316)

改进#

F2PY 改进#

  • 生成的扩展模块不再使用已弃用的 NumPy-C API。

  • 改进了 f2py 生成的异常消息。

  • 修复了大量错误和 flake8 警告。

  • 在 signature 文件 C 表达式中可以使用各种 CPP 宏,这些宏都以 f2py_ 为前缀。例如,应该使用 f2py_len(x) 而不是 len(x)

  • 引入了一个新的构造 character(f2py_len=...) 来支持从包装函数返回假定的长度字符字符串(例如 character(len=*))。

引入了一个钩子,用于在读取所有输入文件后重写 f2py 内部数据结构。例如,这对于 SciPy 支持的向后兼容性是必需的,其中字符参数在 C 表达式中被视为字符字符串参数。

(gh-19388)

IBM zSystems 向量扩展功能(SIMD)#

通过通用内建接口(universal intrinsics interface)增加了对 zSystem(z13、z14、z15)SIMD 扩展的支持。此支持通过使用通用内建接口实现的 SIMD 内核获得了性能提升,包括以下操作:rint、floor、trunc、ceil、sqrt、absolute、square、reciprocal、tanh、sin、cos、equal、not_equal、greater、greater_equal、less、less_equal、maximum、minimum、fmax、fmin、argmax、argmin、add、subtract、multiply、divide。

(gh-20913)

NumPy 现在会在浮点数转换中发出错误#

在大多数情况下,NumPy 以前在转换过程中发生浮点数警告或错误时不会发出这些警告或错误。例如,转换如下:

np.array([2e300]).astype(np.float32)  # overflow for float32
np.array([np.inf]).astype(np.int64)

现在通常会发出浮点数警告。这些警告应表明发生了浮点数溢出。对于浮点数转换为整数的错误,用户应预期会收到无效值警告。

用户可以使用 np.errstate 修改这些警告的行为。

请注意,对于浮点数到整数的转换,实际发出的警告可能取决于平台。例如:

arr = np.full(100, fill_value=1000, dtype=np.float64)
arr.astype(np.int8)

可能返回一个等效于(中间转换意味着不发出警告)的结果。

arr.astype(np.int64).astype(np.int8)

可能返回未定义的结果,并设置警告。

RuntimeWarning: invalid value encountered in cast

具体行为取决于 C99 标准及其在软件和硬件中的实现。

(gh-21437)

F2PY 支持 value 属性#

Fortran 标准要求,带有 value 属性声明的变量必须按值传递而不是按引用传递。F2PY 现在可以正确支持此用法。因此,Fortran 代码中的 integer, intent(in), value :: x 将生成正确的包装器。

(gh-21807)

为第三方 BitGenerators 添加了 pickle 支持#

位生成器的 pickle 格式已扩展,允许每个位生成器在 pickle 时提供自己的构造函数。以前版本的 NumPy 只支持反 pickle 由 NumPy 附带的核心位生成器创建的 Generator 实例。尝试反 pickle 使用第三方位生成器的 Generator 将会失败,因为反 pickle 时使用的构造函数仅了解 NumPy 中包含的位生成器。

(gh-22014)

arange() 现在明确拒绝 dtype=str#

以前,np.arange(n, dtype=str) 函数在 n=1n=2 时工作,但对于其他 n 值会引发非特定的异常消息。现在,它会引发 TypeError,告知 arange 不支持字符串 dtype。

>>> np.arange(2, dtype=str)
Traceback (most recent call last)
   ...
TypeError: arange() not supported for inputs with DType <class 'numpy.dtype[str_]'>.

(gh-22055)

numpy.typing 协议现在可以进行运行时检查#

numpy.typing.ArrayLikenumpy.typing.DTypeLike 中使用的协议现在已正确标记为可进行运行时检查,这使得它们更容易用于运行时类型检查器。

(gh-22357)

性能改进和更改#

整数数组的 np.isinnp.in1d 的更快版本#

np.in1d(由 np.isin 使用)在传入两个整数数组时,现在可以切换到更快的算法(速度提高高达 10 倍以上)。这通常是自动使用的,但您可以使用 kind="sort"kind="table" 来强制使用旧的或新的方法,分别。

(gh-12065)

更快的比较运算符#

比较函数(numpy.equalnumpy.not_equalnumpy.lessnumpy.less_equalnumpy.greaternumpy.greater_equal)现在速度快得多,因为它们现在已经通过通用内建指令进行了矢量化。对于具有 SIMD 扩展 AVX512BW 的 CPU,整数、浮点数和布尔数据类型的性能增益分别高达 2.57 倍、1.65 倍和 19.15 倍(N=50000)。

(gh-21483)

更改#

更好的整数除法溢出报告#

标量和数组的整数除法溢出以前会提供 RuntimeWarning,返回值未定义,有时会导致崩溃。

>>> np.array([np.iinfo(np.int32).min]*10, dtype=np.int32) // np.int32(-1)
<stdin>:1: RuntimeWarning: divide by zero encountered in floor_divide
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

整数除法溢出现在返回输入 dtype 的最小值,并引发以下 RuntimeWarning

>>> np.array([np.iinfo(np.int32).min]*10, dtype=np.int32) // np.int32(-1)
<stdin>:1: RuntimeWarning: overflow encountered in floor_divide
array([-2147483648, -2147483648, -2147483648, -2147483648, -2147483648,
       -2147483648, -2147483648, -2147483648, -2147483648, -2147483648],
      dtype=int32)

(gh-21506)

masked_invalid 现在会就地修改掩码#

当与 copy=False 一起使用时,numpy.ma.masked_invalid 现在会就地修改输入蒙版数组。这使其行为与 masked_where 完全相同,并且更符合文档。

(gh-22046)

nditer/NpyIter 允许分配所有操作数#

通过 Python 中的 np.nditer 和 C 中的 NpyIter 可用的 NumPy 迭代器现在支持分配所有数组。在这种情况下,迭代器形状默认为 ()。必须提供操作数的数据类型 (dtype),因为无法从其他输入推断出“通用数据类型”。

(gh-22457)