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 的不同之处在于,由轴索引的子数组被置换,而不是将轴视为其他索引的每个组合的单独的 1-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.int64numpy.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 参数的函数已被弃用#

以前,这是传递 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 , Uint64Datetime64 已被弃用.应使用小写变体.对于字节和字符串, "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 )

未来变化#

数组不能使用子数组 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"]

通常可以使用此选项来选择加入新的行为.

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

( 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 中删除. 已删除的函数包括 fv , ipmt , irr , mirr , nper , npv , pmt , ppmt , pvrate . 这些函数可在 numpy_financial 库中使用.

( gh-17067 )

兼容性说明#

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

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

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

在使用 axis=None 的 concatenate 中的 Same kind 强制转换#

当使用 axis=None 调用 concatenate 时,展平的数组使用 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 float)仍将强制执行统一的字符串长度:

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.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#

Float 类型和 timedelta 类型的提升始终会引发 TypeError. np.promote_types("float32", "m8") 现在与 np.promote_types("m8", "float32") 对齐,并且都会引发 TypeError. 之前, np.promote_types("float32", "m8") 返回 "m8" ,这被认为是一个 bug.

Uint64 类型和 timedelta 类型的提升始终会引发 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 且推断出了结构化数据类型),则 numpy.genfromtxt 无法解包.例如:

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

mgrid , r_ 等始终为非默认精度输入返回正确的输出#

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

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

新特性#

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

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

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

where 关键字参数用于 numpy 函数 mean , std , var#

添加了关键字参数 where ,允许限制 mean , stdvar 的计算范围,仅限于元素的子集.它可以通过直接 numpynumpy.ndarray 的方法获得.

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

( gh-15852 )

norm=backward , forward 关键字选项用于 numpy.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 存根运行 mypy 需要以下任一操作:

  • 安装 NumPy

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

这两种选择都有些不方便,因此添加一个 --mypy 选项到 runtests,它可以处理为您设置的事情.这在将来对于任何类型代码生成也很有用,因为它将确保在类型检查之前构建项目.

( 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 编译器的支持,nvfortran 是 pgfortran 的一个版本.

( gh-17344 )

dtype 选项用于 covcorrcoef#

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 )

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

这使得 SciPy 可以在 AIX 上构建.

( 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 用于显式禁用所有新改进,它还添加了一个新的 C 编译器 #definition,称为 NPY_DISABLE_OPTIMIZATION ,可以用作任何 SIMD 代码的保护.

  • 高级 CPU 调度程序

    一个灵活的跨架构 CPU 调度程序,构建在 Python/Numpy distutils 之上,支持具有各种 CPU 功能的所有常见编译器.

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

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

    该头文件由 distutils 模块 ccompiler_opt 生成,包含通过命令参数"–cpu-baseline"和"–cpu-dispatch"配置的所有指令集的 #definitions 和头文件.

  • 新的 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.linspace 中使用 int 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 )