NumPy 1.24 发行说明#

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

  • 许多新的弃用,检查一下.

  • 许多过期的弃用,

  • 新的 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 % 28 也可能效果很好.

在极少数情况下,输入数据可能混合了负值和非常大的无符号值(即 -1263 ).不幸的是,这里有必要对 Python 值使用 % ,或者根据是否需要负值使用有符号或无符号转换.

( gh-22385 )

弃用 msort#

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

( gh-22456 )

np.str0 和类似的现在已弃用#

以 0 位大小结尾的标量类型别名: np.object0 , np.str0 , np.bytes0 , np.void0 , np.int0 , np.uint0 以及 np.bool8 现在已弃用,最终将被删除.

( gh-22607 )

已过期的弃用#

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

    ( gh-21645 )

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

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

  • 现在,将规范 (主要是本机字节序) 之外的 dtype 实例传递给 ufunc 中的 dtype=signature= 将引发 TypeError .我们建议传递字符串 "int8" 或标量类型 np.int8 ,因为字节序,datetime/timedelta 单位等永远不会被强制执行.(最初在 NumPy 1.21 中已弃用.)

    ( gh-22540 )

  • 比较 ufunc 的 dtype= 参数现在可以正确应用.这意味着只有 boolobject 是有效值,并且强制执行 dtype=object .

    ( gh-22541 )

  • 别名 np.object , np.bool , np.float , np.complex , np.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

在更改之前,由于 new is arrTrue ,因此 dtype 不匹配.

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

请注意,多项式类仅支持 1D 多项式,因此当结果为多元时,不允许涉及具有不同符号的多项式的操作:

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

strict 选项用于 testing.assert_array_equal#

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

( gh-21595 )

新参数 equal_nan 添加到 np.unique#

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

( gh-21623 )

castingdtype 关键字参数用于 numpy.stack#

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

castingdtype 关键字参数用于 numpy.vstack#

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

castingdtype 关键字参数用于 numpy.hstack#

现在 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 来直接构造结构化的 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 修改这些警告的行为.

请注意,对于float到int的转换,给出的确切警告可能取决于平台.例如:

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 支持#

扩展了 bit 生成器的 pickle 格式,以允许每个 bit 生成器在 pickle 期间提供自己的构造函数.以前的 NumPy 版本仅支持对使用 NumPy 提供的核心 bit 生成器集之一创建的 Generator 实例进行 unpickling.尝试 unpickle 使用第三方 bit 生成器的 Generator 将会失败,因为 unpickling 期间使用的构造函数仅知道 NumPy 中包含的 bit 生成器.

( gh-22014 )

arange() 現在會明確地在使用 dtype=str 時出錯#

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

>>> 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.equal , numpy.not_equal , numpy.less , numpy.less_equal , numpy.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 array.这使其行为与 masked_where 完全相同,并且更好地匹配文档.

( gh-22046 )

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

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

( gh-22457 )