NumPy 1.24 发布说明#

NumPy 1.24.0 版本继续进行改进 dtypes 处理和推广、提高执行速度以及澄清文档的工作.由于推广和清理的变化,还有大量新的和过时的弃用.这可能被称为一个弃用版本.亮点是

  • 许多新的弃用,查看它们.

  • 许多已过时的弃用,

  • 新的 F2PY 功能和修复.

  • 新的”dtype”和”casting”关键字用于堆叠函数.

详情请见下方,

此版本支持 Python 版本 3.8-3.11.

弃用#

弃用 fastCopyAndTranspose 和 PyArray_CopyAndTranspose#

numpy.fastCopyAndTranspose 函数已被弃用.请直接使用相应的复制和转置方法:

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)

过时的弃用#

  • normed 关键字参数已从 np.histogram, np.histogram2d, 和 np.histogramdd 中移除.请改用 density.如果 normed 是通过位置传递的,现在使用 density.

    (gh-21645)

  • 现在,创建不规则数组将始终引发 ValueError,除非传递了 dtype=object.这包括非常深层次嵌套的序列.

    (gh-22004)

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

  • 对 Windows Interix POSIX 互操作层的支持已被移除.

    (gh-22139)

  • 对 Cygwin < 3.3 的支持已被移除.

    (gh-22159)

  • np.ma.MaskedArray 的 mini() 方法已被移除.请使用 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 实例传递给 dtype=signature= 现在将引发 TypeError.我们建议传递字符串 "int8" 或标量类型 np.int8,因为字节顺序、日期时间/时间增量单位等从未被强制执行.(最初在 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)

子数组到对象的转换现在会复制#

将包含子数组的 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)

现在总是为假.虽然以前在特定情况下它是真.

(gh-21925)

返回的数组尊重 dtype kwarg 对象的唯一性#

当使用 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 后回退到缓冲区协议或 __array_interface__.

(gh-22542)

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

Ubuntu 18.04 已弃用于 GitHub actions,并且 GCC-6 在 Ubuntu 20.04 上不可用,因此使用该编译器的构建不再进行测试.我们仍然测试使用 GCC-7 和 GCC-8 的构建.

(gh-22598)

新功能#

多项式类新增 symbol 属性#

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 x

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

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

  • 字符串数组(例如 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 选项#

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

(gh-21595)

新增参数 equal_nannp.unique#

np.unique 在 1.21 版本中进行了更改,将所有 NaN 值视为相等并返回一个 NaN.设置 equal_nan=False 将恢复到 1.21 版本之前的行为,将 NaNs 视为唯一.默认为 True.

(gh-21623)

numpy.stackcastingdtype 关键字参数#

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

numpy.vstackcastingdtype 关键字参数#

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

numpy.hstackcastingdtype 关键字参数#

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

(gh-21627)

单例 RandomState 下的位生成器可以被更改#

numpy.random 模块中暴露的单例 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 直接构造结构化空标量.

(gh-22316)

改进#

F2PY 改进#

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

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

  • 众多错误和 flake8 警告修复

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

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

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

(gh-19388)

IBM zSystems 向量扩展设施 (SIMD)#

通过通用内在函数接口,增加了对 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 支持值属性#

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

(gh-21807)

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

位生成器的 pickle 格式被扩展,以允许每个位生成器在序列化时提供自己的构造函数.NumPy 的早期版本仅支持解序列化使用 NumPy 提供的核心位生成器集创建的 Generator 实例.尝试解序列化使用第三方位生成器的 Generator 会失败,因为在解序列化过程中使用的构造函数只识别 NumPy 中包含的位生成器.

(gh-22014)

arange() 现在在使用 dtype=str 时会明确失败#

之前,``np.arange(n, dtype=str)`` 函数在 n=1n=2 时工作正常,但对于其他 n 值会引发一个不明确的异常信息.现在,它会引发一个 TypeError,告知 arange 不支持字符串数据类型:

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

整数除法溢出现在返回输入数据类型的最小值并引发以下 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,因为无法从其他输入推断出”通用dtype”.

(gh-22457)