NumPy 1.20.0 发布说明#

这个 NumPy 版本是有史以来最大的发布,由 184 人贡献的 684 个 PR 已经被合并.有关更多详细信息,请参见下面的亮点列表.此版本支持的 Python 版本是 3.7-3.9,已放弃对 Python 3.6 的支持.亮点是

  • NumPy 函数的注解.这项工作正在进行中,可以根据用户的反馈预期改进.

  • 更广泛地使用 SIMD 以提高 ufuncs 的执行速度.在引入通用函数方面已经做了大量工作,这些函数将简化现代特性在不同硬件平台上的使用.这项工作正在进行中.

  • 在改变 dtype 和 casting 实现的工作中,为了提供一个更容易扩展 dtypes 的路径.这项工作正在进行中,但已经完成了足够的工作,允许进行实验和反馈.

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

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

  • 即将推出的 Cython 3.0 的初步支持.

新功能#

random.Generator 类有一个新的 permuted 函数.#

新函数与 shufflepermutation 的不同之处在于,由轴索引的子数组被置换,而不是将轴视为每个其他索引组合的单独 1-D 数组.例如,现在可以置换 2-D 数组的行或列.

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

为了给大多数情况提供一个明确的指导方针,对于 boolobjectstr``(和 ``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 外部调用如 numpy.add.outer 一起使用.以前,矩阵在这里被转换为数组.未来将不会自动进行这种转换,需要手动转换为数组.

(gh-16232)

进一步的数值样式类型已弃用#

剩余的数字样式类型代码 Bytes0, Str0, Uint32, Uint64, 和 Datetime64 已被弃用.应改用小写变体.对于字节和字符串,``”S”`` 和 "U" 是进一步的替代方案.

(gh-16554)

ndindexndincr 方法已被弃用#

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

(gh-17233)

未定义 __len____getitem__ 的 ArrayLike 对象#

定义了 __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)

未来变化#

数组不能使用子数组的数据类型#

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

对于这样的 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)

过时的弃用#

  • 数值样式类型代码 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 中移除.已移除的函数包括 fvipmtirrmirrnpernpvpmtppmtpvrate.这些函数在 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).

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

axis=None 的情况下进行相同类型的拼接#

当调用 concatenate 时使用 axis=None,扁平化数组会使用 unsafe 进行转换.其他任何轴的选择使用 “same kind”.这种不同的默认行为已被弃用,将改为使用 “same kind” 转换.新的 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 的).与有符号整数不同,无符号整数不保留这个特殊情况,因为它们的行为总是更像类型转换.以下代码停止引发错误:

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=”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”)``和其他数字样式(大写)类型的弃用保持同步.这些类型已从``np.sctypeDict``和``np.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#

浮点和 timedelta 提升一致地引发 TypeError.``np.promote_types(“float32”, “m8”)`` 现在与 np.promote_types("m8", "float32") 一致,两者都引发 TypeError.以前,``np.promote_types(“float32”, “m8”)`` 返回 "m8",这被认为是一个错误.

Uint64 和 timedelta 的提升一致地引发 TypeError.``np.promote_types(“uint64”, “m8”)`` 现在与 np.promote_types("m8", "uint64") 一致,两者都引发 TypeError.之前,``np.promote_types(“uint64”, “m8”)`` 返回 "m8",这被认为是一个错误.

(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_ 当使用默认的 float64complex128 以外的 dtype 和等效的 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 实例的方法(如 np.polymul)的输出数据类型.

(gh-17577)

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

Python 2.7 C-API 函数的用法已更新为仅适用于 Python 3.需要旧版本的用户应从 NumPy 的旧版本中获取.

(gh-17580)

np.array 中的空数据类型发现#

在使用 np.array(..., dtype="V")arr.astype("V") 和类似的调用中,除非所有元素具有相同的空长度,否则现在会正确引发 TypeError.一个例子是:

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

之前返回的数组具有 dtype "V2",无法忠实地表示 b"1".

(gh-17706)

C API 变化#

PyArray_DescrCheck 宏被修改#

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

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

从 NumPy 1.20 开始,针对早期版本编译的代码将与 NumPy 1.20 的 API 不兼容.解决方法是针对 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)

新功能#

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

关键字参数 where 被添加,并允许在 allany 的布尔评估中仅考虑数组中的指定元素或子轴.这个新关键字可以通过 numpy 直接或在 numpy.ndarray 的方法中用于函数 allany.

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

numpy 函数的 meanstdvarwhere 关键字参数#

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

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

(gh-15852)

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

关键字参数选项 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存根的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 构建#

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

(gh-17284)

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

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

(gh-17344)

covcorrcoefdtype 选项#

dtype 选项现在可用于 numpy.covnumpy.corrcoef.它指定返回结果应具有的数据类型.默认情况下,函数仍然返回 numpy.float64 结果.

(gh-17456)

改进#

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

numpy.polynomial 中的所有六种多项式类型的字符串表示 (__str__) 已更新,以给出多项式的数学表达式,而不是系数数组.多项式表达式有两种全包格式 - 一种使用 Unicode 字符表示上标和下标,另一种仅使用 ASCII 字符.

(gh-15666)

移除 Accelerate 库作为候选 LAPACK 库#

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 的支持已添加,以使用关键字参数提供输出 dtypecasting.``dtype`` 参数不能与 out 参数一起提供.

(gh-16134)

线程安全 f2py 回调函数#

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

(gh-16519)

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

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

(gh-16675)

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

这允许 SciPy 在 AIX 上构建.

(gh-16710)

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

numpy.distutils.fcompiler 中,Fortran Portland Group 编译器的编译命令选择发生了变化.这仅影响链接命令.这会强制使用命令行选项提供的可执行文件(如果提供),而不是 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 以避免关于已弃用 API 使用的 C 编译器警告.

(gh-16986)

使窗口函数完全对称#

确保 NumPy 提供的窗口函数是对称的.之前由于数值精度问题,存在一些小的对称偏差,现在通过更好地安排计算来避免这些偏差.

(gh-17195)

性能提升和变化#

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

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

  • New Build Arguments

    • --cpu-baseline 用于指定所需的最小优化集合,默认值是 min,它提供了可以在广泛的用户平台上安全运行的最小 CPU 特性.

    • --cpu-dispatch 用于指定一组额外的优化调度,默认值是 max -xop -fma4,它启用了所有CPU特性,除了AMD的遗留特性.

    • --disable-optimization 用于显式禁用所有新改进,它还添加了一个新的 C 编译器 #定义 称为 NPY_DISABLE_OPTIMIZATION,它可以作为任何 SIMD 代码的守卫.

  • Advanced CPU dispatcher

    一个灵活的跨架构 CPU 调度器,建立在 Python/Numpy distutils 之上,支持所有常见的编译器,并具有广泛的 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#

在使用 int dtype 的 numpy.linspace 时,以前浮点值会向零舍入.现在改为使用 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)