NumPy 1.20.0 发行说明#

本次 NumPy 发布是迄今为止规模最大的一次,合并了来自 184 人的 684 个拉取请求 (PR)。有关更多详细信息,请参阅下面的亮点列表。此版本支持的 Python 版本为 3.7-3.9,对 Python 3.6 的支持已停止。亮点包括:

  • NumPy 函数的注解。这项工作正在进行中,根据用户反馈,预计会有改进。

  • 更广泛地使用 SIMD 来提高 ufunc 的执行速度。在引入通用函数方面做了大量工作,这些函数将简化跨不同硬件平台使用现代功能。这项工作正在进行中。

  • 在更改 dtype 和类型转换实现方面的初步工作,以便为扩展 dtype 提供更简单的路径。这项工作正在进行中,但已完成足够多的工作以允许实验和反馈。

  • 广泛的文档改进,包括约 185 个 PR 合并。这项工作正在进行中,是改进 NumPy 在线形象和对新用户的有用性的更大项目的一部分。

  • 进一步清理与移除 Python 2.7 相关的内容。这提高了代码可读性并消除了技术债务。

  • 对即将发布的 Cython 3.0 的初步支持。

新函数#

random.Generator 类新增了 permuted 函数。#

这个新函数与 shufflepermutation 的区别在于,按轴索引的子数组会被排列,而不是将轴视为其他索引的每个组合的单独一维数组。例如,现在可以排列二维数组的行或列。

(gh-15121)

sliding_window_view 为 numpy 数组提供滑动窗口视图#

numpy.lib.stride_tricks.sliding_window_view 构建 numpy 数组上的视图,提供对数组的滑动或移动窗口访问。这允许简单实现某些算法,例如移动平均。

(gh-17394)

numpy.broadcast_shapes 是一个面向用户的新函数#

broadcast_shapes 获取给定形状元组相互广播后的结果形状。

>>> np.broadcast_shapes((1, 2), (3, 1))
(3, 2)

>>> np.broadcast_shapes(2, (3, 1))
(3, 2)

>>> np.broadcast_shapes((6, 7), (5, 6, 1), (7,), (5, 1, 7))
(5, 6, 7)

(gh-17535)

弃用#

使用 np.int 等内置类型别名已弃用#

长期以来,np.int 一直是内置 int 的别名。这反复导致新用户感到困惑,并且主要出于历史原因而存在。

这些别名已被弃用。下表显示了弃用别名的完整列表及其确切含义。用第二列的内容替换第一列中的项的使用将具有相同的功能并消除弃用警告。

第三列列出了可能偶尔更受青睐的其他 NumPy 名称。另请参阅数据类型以获取更多详细信息。

弃用名称

等同于

NumPy 标量类型名称

numpy.bool

bool

numpy.bool_

numpy.int

int

numpy.int_ (默认), numpy.int64, 或 numpy.int32

numpy.float

float

numpy.float64, numpy.float_, numpy.double (等效)

numpy.complex

complex

numpy.complex128, numpy.complex_, numpy.cdouble (等效)

numpy.object

object

numpy.object_

numpy.str

str

numpy.str_

numpy.long

int

numpy.int_ (C long), numpy.longlong (最大整数类型)

numpy.unicode

str

numpy.unicode_

对于绝大多数情况,为了给出明确的指导方针,对于类型 bool, object, str (和 unicode) 使用普通版本更简洁明了,通常是一个很好的替代品。对于 floatcomplex,如果您希望对精度更明确,可以使用 float64complex128

对于 np.int,直接替换为 np.int_int 也是不错的选择,并且不会改变行为,但精度将继续取决于计算机和操作系统。如果您想更明确并审查当前用法,您有以下替代方案:

  • np.int64np.int32 以精确指定精度。这确保结果不会取决于计算机或操作系统。

  • np.int_int (默认),但请注意它取决于计算机和操作系统。

  • C 类型:np.cint (int), np.int_ (long), np.longlong

  • np.intp,在 32 位机器上是 32 位,在 64 位机器上是 64 位。这可能是用于索引的最佳类型。

当与 np.dtype(...)dtype=... 一起使用时,将其更改为上述 NumPy 名称不会对输出产生影响。如果作为标量使用,则:

np.float(123)

改变它会微妙地改变结果。在这种情况下,Python 版本 float(123)int(12.) 通常更受青睐,尽管 NumPy 版本可能有助于与 NumPy 数组保持一致性(例如,NumPy 在零除等操作上的行为不同)。

(gh-14882)

shape=None 传递给具有非可选形状参数的函数已弃用#

以前,这等同于传递 shape=()。此弃用由 C API 中的 PyArray_IntpConverter 发出。如果您的 API 旨在支持传递 None,那么您应该在调用转换器之前检查 None,以便能够区分 None()

(gh-15886)

即使索引结果为空,也会报告索引错误#

将来,当整数数组索引包含超出范围的值时,即使未索引维度长度为 0,NumPy 也会引发 IndexError。这现在将发出 DeprecationWarning。这可能发生在数组之前为空,或涉及空切片时

arr1 = np.zeros((5, 0))
arr1[[20]]
arr2 = np.zeros((5, 5))
arr2[[20], :0]

以前,非空索引 [20] 没有被检查正确性。现在它将被检查,导致弃用警告,该警告将转换为错误。这也适用于赋值。

(gh-15900)

modesearchside 的不精确匹配已弃用#

以前,modesearchside 的不精确和不区分大小写的匹配是有效输入,现在将给出 DeprecationWarning。例如,下面是一些现在已弃用并会给出 DeprecationWarning 的用法示例:

import numpy as np
arr = np.array([[3, 6, 6], [4, 5, 1]])
# mode: inexact match
np.ravel_multi_index(arr, (7, 6), mode="clap")  # should be "clip"
# searchside: inexact match
np.searchsorted(arr[0], 4, side='random')  # should be "right"

(gh-16056)

numpy.dual 弃用#

模块 numpy.dual 已弃用。应直接从 NumPy 或 SciPy 导入函数,而不是从 numpy.dual 导入函数。

(gh-16156)

矩阵的 outerufunc.outer 已弃用#

np.matrixouter 或通用 ufunc outer 调用(例如 numpy.add.outer)一起使用。以前,矩阵在这里被转换为数组。将来将不再进行此操作,需要手动转换为数组。

(gh-16232)

进一步弃用 Numeric 样式类型#

剩余的 numeric 样式类型代码 Bytes0, Str0, Uint32, Uint64Datetime64 已被弃用。应改用小写变体。对于字节和字符串,"S""U" 是其他替代方案。

(gh-16554)

ndindexndincr 方法已弃用#

自 NumPy 1.8 以来,文档一直警告不要使用此函数。请改用 next(it) 而不是 it.ndincr()

(gh-17233)

未定义 __len____getitem__ 的类数组对象#

定义了 __array____array_interface____array_struct__ 协议之一但不是序列(通常通过具有 __len____getitem__ 定义)的对象在未来进行数组强制转换时将表现不同。

当嵌套在序列中时,例如 np.array([array_like]),它们被视为单个 Python 对象而不是数组。未来,它们将与以下内容表现相同:

np.array([np.array(array_like)])

此更改仅在 np.array(array_like) 不是 0-D 时才会生效。此警告的解决方案可能取决于对象:

  • 某些类数组对象可能期望新的行为,用户可以忽略该警告。对象可以选择公开序列协议以选择加入新行为。

  • 例如,shapely 将允许使用 line.coords 而不是 np.asarray(line) 转换为类数组对象。用户可以绕过警告,或者在新约定可用时使用新约定。

不幸的是,只有通过调用 np.array(array_like) 才能实现新行为。

如果您希望确保旧行为保持不变,请创建一个对象数组,然后显式填充它,例如:

arr = np.empty(3, dtype=object)
arr[:] = [array_like1, array_like2, array_like3]

这将确保 NumPy 知道不进入类数组对象并将其用作对象。

(gh-17973)

未来变更#

数组不能使用子数组 dtype#

dtype 是子数组 dtype(例如 np.dtype("(2)i,"))时,使用 np.array(arr, dtype)arr.astype(dtype) 创建数组和类型转换将使用不同的逻辑。

对于此类 dtype,以下行为成立:

res = np.array(arr, dtype)

res.dtype is not dtype
res.dtype is dtype.base
res.shape == arr.shape + dtype.shape

res 使用以下逻辑填充:

res = np.empty(arr.shape + dtype.shape, dtype=dtype.base)
res[...] = arr

这使用了不正确的广播(并且经常导致错误)。将来,这将改为单独转换每个元素,导致与以下内容相同的结果:

res = np.array(arr, dtype=np.dtype(["f", dtype]))["f"]

这通常可以用于选择新行为。

此更改不影响 np.array(list, dtype="(2)i,"),除非 list 本身包含至少一个数组。特别是,元组列表的行为保持不变。

(gh-17596)

已过期的弃用#

  • numeric 样式类型代码 np.dtype("Complex64")(大写拼写)的弃用已过期。"Complex64" 对应于 "complex128""Complex32" 对应于 "complex64"

  • np.sctypeNAnp.typeNA 的弃用已过期。两者都已从公共 API 中移除。请改用 np.typeDict

    (gh-16554)

  • np.ctypeslib.ctypes_load_library 的 14 年弃用已过期。请改用 load_library,它完全相同。

    (gh-17116)

金融函数已移除#

根据 NEP 32,金融函数已从 NumPy 1.20 中移除。已移除的函数包括 fv, ipmt, irr, mirr, nper, npv, pmt, ppmt, pvrate。这些函数可在 numpy_financial 库中找到。

(gh-17067)

兼容性说明#

isinstance(dtype, np.dtype) 而不是 type(dtype) is not np.dtype#

NumPy dtypes 不再是 np.dtype 的直接实例。可能使用 type(dtype) is np.dtype 的代码将始终返回 False,并且必须更新为使用正确的版本 isinstance(dtype, np.dtype)

如果针对早于 1.16.6 的 NumPy 版本编译,此更改还会影响 C 端的宏 PyArray_DescrCheck。如果代码使用此宏并希望针对旧版 NumPy 编译,则必须替换该宏(另请参阅C API 更改部分)。

axis=None 的 concatenate 中进行同类型转换#

当调用 concatenate 并设置 axis=None 时,扁平化数组会以 unsafe 方式进行类型转换。任何其他轴选择都使用“同类型”。这种不同的默认行为已被弃用,将改为使用“同类型”类型转换。可以使用新的 casting 关键字参数来保留旧行为。

(gh-16134)

NumPy 标量在赋值给数组时进行类型转换#

在创建数组或向数组赋值时,在所有相关情况下,NumPy 标量现在将与 NumPy 数组完全相同地进行类型转换。特别是,这改变了以前在某些情况下引发错误的行为:

np.array([np.float64(np.nan)], dtype=np.int64)

将成功并返回未定义的结果(通常是最小可能的整数)。这也影响赋值:

arr[0] = np.float64(np.nan)

目前,NumPy 保留了以下行为:

np.array(np.float64(np.nan), dtype=np.int64)

上述更改不影响 Python 标量:

np.array([float("NaN")], dtype=np.int64)

保持不变(np.nan 是 Python float,而不是 NumPy float)。与有符号整数不同,无符号整数不保留此特殊情况,因为它们的行为更像类型转换。以下代码不再引发错误:

np.array([np.float64(np.nan)], dtype=np.uint64)

为避免向后兼容性问题,目前仍支持将 datetime64 标量赋值给长度过短的字符串。这意味着 np.asarray(np.datetime64("2020-10-10"), dtype="S5") 现在成功,而以前会失败。从长远来看,这可能会被弃用,或者普遍允许不安全的类型转换,以使数组和标量的赋值行为保持一致。

字符串和其他类型混合时的数组强制转换更改#

当字符串和其他类型混合时,例如

np.array(["string", np.float64(3.)], dtype="S")

结果将发生变化,这在某些情况下可能导致字符串 dtype 具有更长的字符串。特别是,如果未提供 dtype="S",任何数值都将导致足够长以容纳所有可能数值的字符串结果。(例如,浮点数为“S32”)。请注意,在将非字符串转换为字符串时,应始终提供 dtype="S"

如果提供了 dtype="S",结果将与以前大致相同,但 NumPy 标量(而不是像 1.0 这样的 Python 浮点数)仍将强制执行统一的字符串长度。

np.array([np.float64(3.)], dtype="S")  # gives "S32"
np.array([3.0], dtype="S")  # gives "S3"

以前第一个版本给出与第二个版本相同的结果。

数组强制转换重构#

数组强制转换已重构。一般来说,这不应影响用户。在极少数的边缘情况下,当类数组对象嵌套时:

np.array([array_like1])

现在事情将与以下内容更加一致:

np.array([np.array(array_like1)])

这可能微妙地改变某些定义不佳的类数组对象的输出。其中一个例子是并非也匹配形状序列的类数组对象。在 NumPy 1.20 中,当类数组对象并非也是序列时,将发出警告(但行为保持不变,参见弃用)。如果类数组对象也是序列(定义 __getitem____len__),NumPy 现在将仅使用 __array____array_interface____array_struct__ 给出的结果。当(嵌套)序列描述不同形状时,这将导致差异。

(gh-16200)

写入 numpy.broadcast_arrays 的结果将导出只读缓冲区#

在 NumPy 1.17 中,当写入 numpy.broadcast_arrays 的结果数组时,会开始发出警告。当通过缓冲区接口(例如 memoryview(arr))使用数组时,此警告会被跳过。现在,对于 __array_interface____array_struct__ 这两种协议,同样的事情将发生,它们将返回只读缓冲区,而不是发出警告。

(gh-16350)

数字样式类型名称已从类型字典中移除#

为了与 np.dtype("Complex64") 和其他 numeric 样式(大写)类型的弃用保持同步。这些已从 np.sctypeDictnp.typeDict 中移除。您应该改用小写版本。请注意,"Complex64" 对应于 "complex128""Complex32" 对应于 "complex64"。NumPy 样式(新)版本表示完整大小,而不是实部/虚部的大小。

(gh-16554)

operator.concat 函数现在对数组参数引发 TypeError#

以前的行为是回退到加法并添加两个数组,这被认为对于连接函数来说是意外的行为。

(gh-16570)

nickname 属性已从 ABCPolyBase 中移除#

抽象属性 nickname 已从 ABCPolyBase 中移除,因为它在派生的便捷类中不再使用。这可能会影响从 ABCPolyBase 派生类并重写了表示和显示方法(例如 __str____repr___repr_latex 等)的用户。

(gh-16589)

float->timedeltauint64->timedelta 提升将引发 TypeError#

浮点数和时间增量类型提升一致地引发 TypeError。np.promote_types("float32", "m8") 现在与 np.promote_types("m8", "float32") 对齐,并且两者都引发 TypeError。以前,np.promote_types("float32", "m8") 返回 "m8",这被认为是一个 bug。

Uint64 和时间增量类型提升一致地引发 TypeError。np.promote_types("uint64", "m8") 现在与 np.promote_types("m8", "uint64") 对齐,并且两者都引发 TypeError。以前,np.promote_types("uint64", "m8") 返回 "m8",这被认为是一个 bug。

(gh-16592)

numpy.genfromtxt 现在正确解包结构化数组#

以前,如果 numpy.genfromtxt 在调用时使用 unpack=True 并且将结构化数据类型传递给 dtype 参数(或传递 dtype=None 并推断出结构化数据类型),则会解包失败。例如:

>>> data = StringIO("21 58.0\n35 72.0")
>>> np.genfromtxt(data, dtype=None, unpack=True)
array([(21, 58.), (35, 72.)], dtype=[('f0', '<i8'), ('f1', '<f8')])

结构化数组现在将正确解包为数组列表,每列一个:

>>> np.genfromtxt(data, dtype=None, unpack=True)
[array([21, 35]), array([58., 72.])]

(gh-16650)

mgridr_ 等对于非默认精度输入始终返回正确输出#

以前,np.mgrid[np.float32(0.1):np.float32(0.35):np.float32(0.1),]np.r_[0:10:np.complex64(3j)] 无法返回有意义的输出。此错误可能影响 mgridogridr_c_,当使用 dtype 不是默认 float64complex128 及其等效 Python 类型的输入时。这些方法已修复以正确处理不同精度。

(gh-16815)

形状不匹配的布尔数组索引现在正确引发 IndexError#

以前,如果布尔数组索引匹配索引数组的大小但不匹配形状,在某些情况下会被错误地允许。在其他情况下,它会引发错误,但错误错误地是 ValueError,消息是关于广播而不是正确的 IndexError

例如,以下代码以前错误地给出 ValueError: operands could not be broadcast together with shapes (2,2) (1,4)

np.empty((2, 2))[np.array([[True, False, False, False]])]

而以下代码以前错误地返回 array([], dtype=float64)

np.empty((2, 2))[np.array([[False, False, False, False]])]

现在两者都正确地给出 IndexError: boolean index did not match indexed array along dimension 0; dimension is 2 but corresponding boolean dimension is 1

(gh-17010)

类型转换错误中断迭代#

在迭代并进行类型转换时,错误可能会比以前更早地停止迭代。无论如何,失败的类型转换操作总是返回未定义的部分结果。这些结果现在可能更加未定义和部分。对于 NpyIter C-API 的用户,此类类型转换错误现在将导致 iternext() 函数返回 0,从而中止迭代。目前,没有直接检测此类错误的 API。有必要检查 PyErr_Occurred(),这可能与 NpyIter_Reset 结合使用时出现问题。这些问题一直存在,但如果用户需要,可以添加新的 API。

(gh-17029)

f2py 生成的代码可能返回 unicode 而不是字节字符串#

f2py 生成代码以前返回的一些字节字符串现在可能是 unicode 字符串。这是 Python2 -> Python3 清理的结果。

(gh-17068)

__array_interface__["data"] 元组的第一个元素必须是整数#

这多年来一直是文档中说明的接口,但仍然有一些代码会接受指针地址的字节字符串表示。这些代码已被移除,现在将地址作为字节字符串传递将引发错误。

(gh-17241)

poly1d 尊重全零参数的 dtype#

以前,使用全零系数构造 poly1d 实例会将系数转换为 np.float64。这影响了内部构造 poly1d 实例的方法的输出 dtype,例如 np.polymul

(gh-17577)

用于 swig 的 numpy.i 文件仅支持 Python 3。#

Python 2.7 C-API 函数的使用已更新为仅支持 Python 3。需要旧版本的用户应从旧版本的 NumPy 中获取。

(gh-17580)

np.array 中的 void dtype 发现#

在使用 np.array(..., dtype="V"), arr.astype("V") 和类似调用的情况下,现在除非所有元素具有相同的 void 长度,否则将正确引发 TypeError。例如:

np.array([b"1", b"12"], dtype="V")

以前返回的数组的 dtype 为 "V2",无法忠实地表示 b"1"

(gh-17706)

C API 更改#

PyArray_DescrCheck 宏已修改#

自 NumPy 1.16.6 以来,PyArray_DescrCheck 宏已更新为:

#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)

从 NumPy 1.20 开始,针对早期版本编译的代码将与 NumPy 1.20 不兼容。修复方法是针对 1.16.6 编译(如果 NumPy 1.16 版本是您希望支持的最旧版本),或者通过将其替换为新定义来手动内联宏:

PyObject_TypeCheck(op, &PyArrayDescr_Type)

这与所有 NumPy 版本兼容。

np.ndarraynp.void_ 的大小已更改#

PyArrayObjectPyVoidScalarObject 结构的大小已更改。以下头文件定义已移除:

#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))

因为大小不应被视为编译时常量:它会随 NumPy 的不同运行时版本而改变。

最可能相关的用途是可能用 C 编写的子类,它们必须重新编译并应该更新。请参阅 PyArrayObject 的文档以获取更多详细信息,如果您受到此更改的影响,请联系 NumPy 开发人员。

NumPy 将尝试给出优雅的错误,但期望固定结构大小的程序可能会有未定义的行为并可能崩溃。

(gh-16938)

新特性#

numpy.allnumpy.any 函数的 where 关键字参数#

添加了关键字参数 where,允许在 allany 的布尔评估中仅考虑数组中指定的元素或子轴。此新关键字可通过 numpy 直接使用,也可在 numpy.ndarray 的方法中使用。

任何可广播的布尔数组或标量都可以设置为 where。如果用户未设置 where,它默认为 True,以评估数组中所有元素的函数。示例在函数的文档中给出。

NumPy 函数 meanstdvarwhere 关键字参数#

添加了关键字参数 where,允许在计算 meanstdvar 时将范围限制为仅包含元素子集。它可以通过 numpy 直接使用,也可以在 numpy.ndarray 的方法中使用。

任何可广播的布尔数组或标量都可以设置为 where。如果用户未设置 where,它默认为 True,以评估数组中所有元素的函数。示例在函数的文档中给出。

(gh-15852)

norm=backward, forwardnumpy.fft 函数的关键字选项#

关键字参数选项 norm=backward 已添加作为 None 的别名,并作为默认选项;使用它时,直接变换未缩放,逆变换按 1/n 缩放。

使用新的关键字参数选项 norm=forward 会使直接变换按 1/n 缩放,而逆变换未缩放(即与默认选项 norm=backward 完全相反)。

(gh-16476)

NumPy 现在是类型化的#

NumPy 的大部分内容已添加类型注解。还有一个新的 numpy.typing 模块,其中包含对最终用户有用的类型。目前可用的类型有:

  • ArrayLike:用于可强制转换为数组的对象

  • DtypeLike:用于可强制转换为 dtype 的对象

(gh-16515)

numpy.typing 可以在运行时访问#

numpy.typing 中的类型现在可以在运行时导入。以下代码将起作用:

from numpy.typing import ArrayLike
x: ArrayLike = [1, 2, 3, 4]

(gh-16558)

f2py 生成的模块新增 __f2py_numpy_version__ 属性。#

由于 f2py 与 NumPy 一同发布,__f2py_numpy_version__ 提供了一种追踪 f2py 用于生成模块的版本的方法。

(gh-16594)

mypy 测试可通过 runtests.py 运行#

目前,使用 NumPy stub 配置运行 mypy 需要:

  • 安装 NumPy

  • 将源目录添加到 MYPYPATH 并链接到 mypy.ini

这两种选项都有些不便,因此为 runtests 添加 --mypy 选项,该选项会处理设置。这在未来对于任何类型代码生成也将非常有用,因为它将确保在类型检查之前构建项目。

(gh-17123)

用户定义 BLAS/LAPACK 检测顺序的否定#

distutils 允许在确定 BLAS/LAPACK 库时否定库。这可用于从库解析阶段中删除某个项目,即,要禁止 NetLIB 库,可以执行:

NPY_BLAS_ORDER='^blas' NPY_LAPACK_ORDER='^lapack' python setup.py build

这将改用任何加速库。

(gh-17219)

允许将优化参数传递给 asv build#

现在,当使用 --bench-compare 参数时,可以将 -j--cpu-baseline--cpu-dispatch--disable-optimization 标志传递给 ASV build。

(gh-17284)

NVIDIA HPC SDK nvfortran 编译器现已支持#

已添加对 nvfortran 编译器的支持,它是 pgfortran 的一个版本。

(gh-17344)

covcorrcoefdtype 选项#

numpy.covnumpy.corrcoef 现在可以使用 dtype 选项。它指定返回结果的数据类型。默认情况下,这些函数仍返回 numpy.float64 结果。

(gh-17456)

改进#

改进了多项式的字符串表示 (__str__)#

numpy.polynomial 中所有六种多项式类型的字符串表示 (__str__) 已更新,以将多项式显示为数学表达式,而不是系数数组。有两种包范围内的多项式表达式格式可用——一种使用 Unicode 字符表示上标和下标,另一种仅使用 ASCII 字符。

(gh-15666)

从候选 LAPACK 库中移除 Accelerate 库#

Apple 不再支持 Accelerate。将其移除。

(gh-15759)

包含多行对象的对象数组具有更易读的 repr#

如果对象数组的元素具有包含换行符的 repr,则换行符将按列对齐。值得注意的是,这改进了嵌套数组的 repr

>>> np.array([np.eye(2), np.eye(3)], dtype=object)
array([array([[1., 0.],
              [0., 1.]]),
       array([[1., 0., 0.],
              [0., 1., 0.],
              [0., 0., 1.]])], dtype=object)

(gh-15997)

Concatenate 支持提供输出 dtype#

已向 concatenate 添加了支持,允许通过关键字参数提供输出 dtypecastingdtype 参数不能与 out 参数一起提供。

(gh-16134)

线程安全的 f2py 回调函数#

f2py 中的回调函数现在是线程安全的。

(gh-16519)

numpy.core.records.fromfile 现在支持文件类对象#

numpy.core.records.fromfile 现在可以使用文件类对象,例如 io.BytesIO

(gh-16675)

distutils 中添加了对 AIX 上的 RPATH 支持#

这允许在 AIX 上构建 SciPy。

(gh-16710)

使用命令行参数指定的 f90 编译器#

numpy.distutils.fcompiler 中 Fortran Portland Group Compiler 的编译器命令选择已更改。这仅影响链接命令。这强制使用命令行选项提供(如果提供)的可执行文件,而不是 pgfortran 可执行文件。如果没有可执行文件提供给命令行选项,它将默认为 pgf90 可执行文件,根据 PGI 文档,它是 pgfortran 的别名。

(gh-16730)

为 Cython 3.0 及更高版本添加 NumPy 声明#

Cython 3.0 的 pxd 声明得到了改进,以避免使用已弃用的 NumPy C-API 功能。使用 Cython 3.0+ 构建的扩展模块,如果使用 NumPy,现在可以设置 C 宏 NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION,以避免 C 编译器关于弃用 API 使用的警告。

(gh-16986)

使窗口函数精确对称#

确保 NumPy 提供的窗口函数是对称的。以前由于数值精度,存在与对称性的小偏差,现在通过更好的计算安排来避免这些偏差。

(gh-17195)

性能改进和变更#

启用多平台 SIMD 编译器优化#

NumPy 基础设施的一系列改进,为 NEP-38 铺平道路,可总结如下:

  • 新的构建参数

    • --cpu-baseline 用于指定所需优化的最小集合,默认值为 min,提供可在各种用户平台上安全运行的最小 CPU 功能。

    • --cpu-dispatch 用于指定额外优化的分派集合,默认值为 max -xop -fma4,它启用所有 CPU 功能,除了 AMD 传统功能。

    • --disable-optimization 明确禁用所有新改进,它还添加了一个名为 NPY_DISABLE_OPTIMIZATION 的新 C 编译器 #定义,可用作任何 SIMD 代码的保护。

  • 高级 CPU 调度程序

    一个基于 Python/Numpy distutils 构建的灵活的跨架构 CPU 调度程序,支持所有常见编译器和广泛的 CPU 特性。

    新的调度程序需要一个特殊的文件扩展名 *.dispatch.c 来标记可调度 C 源。这些源可以多次编译,以便每个编译过程代表特定的 CPU 特性,并提供不同的 #定义和标志,这些定义和标志会影响代码路径。

  • 新的自动生成 C 头文件 ``core/src/common/_cpu_dispatch.h``

    此头文件由 distutils 模块 ccompiler_opt 生成,包含所有通过命令行参数“–cpu-baseline”和“–cpu-dispatch”配置的 #定义和指令集头文件。

  • 新 C 头文件 ``core/src/common/npy_cpu_dispatch.h``

    此头文件包含整个 CPU 调度过程所需的所有实用程序,它也可以被视为连接新基础设施工作与 NumPy CPU 运行时检测的桥梁。

  • 为 NumPy umath 模块添加新属性(Python 级别)

    • __cpu_baseline__ 一个列表,包含根据命令行参数“–cpu-baseline”指定的值,由编译器和平台支持的所需优化的最小集合。

    • __cpu_dispatch__ 一个列表,包含根据命令行参数“–cpu-dispatch”指定的值,由编译器和平台支持的额外优化的分派集合。

  • 在 PytestTester 运行时打印支持的 CPU 功能

(gh-13516)

变更#

整数上的 np.linspace 现在使用 floor#

在使用 numpy.linspaceint dtype 时,以前浮点值会向零取整。现在改用 numpy.floor,它会向 -inf 取整。这改变了负值的结果。例如,以前会得到:

>>> np.linspace(-3, 1, 8, dtype=int)
array([-3, -2, -1, -1,  0,  0,  0,  1])

现在结果是:

>>> np.linspace(-3, 1, 8, dtype=int)
array([-3, -3, -2, -2, -1, -1,  0,  1])

旧的结果仍然可以通过以下方式获得:

>>> np.linspace(-3, 1, 8).astype(int)
array([-3, -2, -1, -1,  0,  0,  0,  1])

(gh-16841)