NumPy 1.13.0 发行说明#

此版本支持 Python 2.7 和 3.4 - 3.6。

亮点#

  • 在某些平台上,像 a + b + c 这样的操作将重用临时变量,从而减少内存使用并加快执行速度。

  • 就地操作会检查输入是否与输出重叠,并创建临时变量以避免问题。

  • 新增的 __array_ufunc__ 属性为类提供了更好的能力来覆盖默认的 ufunc 行为。

  • 新增 np.block 函数用于创建块数组。

新增函数#

  • 新增 np.positive ufunc。

  • 新增 np.divmod ufunc 提供了更高效的 divmod。

  • 新增 np.isnat ufunc 用于测试 NaT 特殊值。

  • 新增 np.heaviside ufunc 用于计算 Heaviside 函数。

  • 新增 np.isin 函数,改进了 in1d

  • 新增 np.block 函数用于创建块数组。

  • 新增 PyArray_MapIterArrayCopyIfOverlap 到 NumPy C-API。

详情请参见下文。

弃用#

  • 调用 np.fixnp.isposinfnp.isneginf 时使用 f(x, y=out) 已弃用 - 参数应以 f(x, out=out) 形式传递,这与其他类似 ufunc 的接口相匹配。

  • 自 1.7 版本以来弃用的 C-API NPY_CHAR 类型编号现在将在运行时引发弃用警告。使用旧版 f2py 构建的扩展需要重新编译才能消除警告。

  • 当应用于维度大于 2 的数组时,np.ma.argsortnp.ma.minimum.reducenp.ma.maximum.reduce 应使用显式的 axis 参数调用,因为此参数的默认值 (None) 与 NumPy 的其余部分 (-100) 不一致。

  • np.ma.MaskedArray.mini 已弃用,因为它几乎复制了 np.MaskedArray.min 的功能。可以使用 np.ma.minimum.reduce 获得完全等效的行为。

  • np.ma.minimumnp.ma.maximum 的单参数形式已弃用。np.maximumnp.ma.minimum(x) 现在应写为 np.ma.minimum.reduce(x),这与 np.minimum 的做法一致。

  • 在非数值 dtype 上调用 ndarray.conjugate 已弃用(它应与 np.conjugate 的行为匹配,后者会抛出错误)。

  • axis 关键字不满足 -a.ndim - 1 <= axis <= a.ndim(其中 a 是正在重塑的数组)时,调用 expand_dims 已弃用。

未来变更#

  • NumPy 1.14 中,具有不同字段名称的结构化数组之间的赋值将发生变化。以前,dst 中的字段会被设置为 src 中同名字段的值。在 NumPy 1.14 中,字段将改为“按位置”赋值:dst 的第 n 个字段将被设置为 src 数组的第 n 个字段。请注意,NumPy 1.12 中引发的 FutureWarning 错误地报告此更改计划在 NumPy 1.13 而不是 NumPy 1.14 中进行。

构建系统变更#

  • numpy.distutils 现在可以使用与 GCC 兼容的编译器自动确定 C 文件依赖项。

兼容性说明#

错误类型变更#

  • 当输入为空时,numpy.hstack() 现在会抛出 ValueError 而不是 IndexError

  • 接受 axis 参数的函数,当该参数超出范围时,现在会抛出 np.AxisError,而不是 IndexErrorValueError 的混合。为了向后兼容,AxisError 继承了这两个错误。

元组对象 dtypes#

对于某些无意中允许的、形式为 (old_dtype, new_dtype) 的晦涩 dtype,其支持已被移除,其中任一 dtype 为或包含 object dtype。作为例外,形式为 (object, [('name', object)]) 的 dtype 仍受支持,因为有现有使用证据。

DeprecationWarning 转为错误#

详情请参见“变更”部分。

  • partition,当使用非整数分区索引时引发 TypeError。

  • NpyIter_AdvancedNew,当 oa_ndim == 0op_axes 为 NULL 时引发 ValueError。

  • negative(bool_),当负号应用于布尔值时引发 TypeError。

  • subtract(bool_, bool_),当布尔值减去布尔值时引发 TypeError。

  • np.equal, np.not_equal,对象标识不会覆盖失败的比较。

  • np.equal, np.not_equal,对象标识不会覆盖非布尔比较。

  • 已移除弃用的布尔索引行为。详情请参见下面的“变更”部分。

  • 已移除弃用的 np.alterdot()np.restoredot()

FutureWarning 变为已更改行为#

详情请参见“变更”部分。

  • numpy.average 保留子类

  • array == Nonearray != None 执行元素级比较。

  • np.equal, np.not_equal,对象标识不覆盖比较结果。

dtypes 现在始终为真#

以前 bool(dtype) 会回退到默认的 Python 实现,该实现会检查 len(dtype) > 0。由于 dtype 对象将 __len__ 实现为记录字段的数量,标量 dtypes 的 bool 会评估为 False,这不符合直觉。现在对于所有 dtypes,bool(dtype) == True

ndarray 子类中不再需要 __getslice____setslice__#

在 Python 2.7 中子类化 np.ndarray 时,不再 _需要_ 在派生类上实现 __*slice__,因为 __*item__ 将正确拦截这些调用。

任何实现了这些方法的代码将与以前完全一样地工作。调用 ``ndarray.__getslice__`` 的代码(例如通过 super(...).__getslice__)现在将发出 DeprecationWarning - 应改用 .__getitem__(slice(start, end))

使用 ...(省略号)索引 MaskedArrays/常量现在返回 MaskedArray#

此行为与 np.ndarray 的行为一致,并考虑了对象 dtype 的 MaskedArrays 中的嵌套数组,以及省略号与其他索引形式的组合。

C API 变更#

空数组上的 GUfuncs 和 NpyIter 轴移除#

现在允许从 NpyIter 中移除大小为零的轴。这可能意味着从 NpyIter 中移除轴的代码在稍后访问被移除维度时需要添加额外的检查。

最大的后续变化是 gufuncs 现在允许具有零大小的内部维度。这意味着 gufunc 现在必须预见到一个空的内部维度,而以前这是不可能的,并且会引发错误。

对于大多数 gufuncs 来说,应该不需要任何更改。然而,现在对于具有 (..., N, M) -> (..., M) 等签名的 gufuncs,如果 N=0,现在无需额外包装代码即可返回有效结果。

PyArray_MapIterArrayCopyIfOverlap 已添加到 NumPy C-API#

类似于 PyArray_MapIterArray,但新增了一个 copy_if_overlap 参数。如果 copy_if_overlap != 0,则检查输入是否与任何其他数组存在内存重叠,并在适当情况下进行复制,以避免在迭代期间修改输入时出现问题。有关更完整的文档,请参阅相关文档。

新增功能#

已添加 __array_ufunc__#

这是重命名并重新设计的 __numpy_ufunc__。任何类,无论是 ndarray 子类还是其他类,都可以定义此方法或将其设置为 None,以覆盖 NumPy 的 ufuncs 的行为。这与 Python 的 __mul__ 和其他二元操作例程的工作方式非常相似。有关此新选项的实现和行为的更详细描述,请参阅文档。API 是临时性的,我们尚不保证向后兼容性,因为可能会根据反馈进行修改。有关更多详细信息,请参阅 NEP 13文档

新增 positive ufunc#

此 ufunc 对应于一元运算符 +,但与 ndarray 上的 + 不同,如果数组值不支持数值操作,它将引发错误。

新增 divmod ufunc#

此 ufunc 对应于 Python 内置的 divmod,并用于在 NumPy 数组上调用 divmod 时实现该功能。np.divmod(x, y) 计算的结果等效于 (np.floor_divide(x, y), np.remainder(x, y)),但比单独调用这些函数快大约两倍。

np.isnat ufunc 用于测试 NaT 特殊日期时间值和时间差值#

新的 ufunc np.isnat 用于查找日期时间(datetime)和时间差(timedelta)数组中特殊 NaT 值的位置。这类似于 np.isnan

np.heaviside ufunc 用于计算 Heaviside 函数#

新函数 np.heaviside(x, h0)(一个 ufunc)用于计算 Heaviside 函数

                   { 0   if x < 0,
heaviside(x, h0) = { h0  if x == 0,
                   { 1   if x > 0.

np.block 函数用于创建块数组#

在当前的堆叠函数 vstackhstackstack 中添加了一个新的 block 函数。这允许同时在多个轴上进行连接,语法类似于数组创建,但元素本身可以是数组。例如

>>> A = np.eye(2) * 2
>>> B = np.eye(3) * 3
>>> np.block([
...     [A,               np.zeros((2, 3))],
...     [np.ones((3, 2)), B               ]
... ])
array([[ 2.,  0.,  0.,  0.,  0.],
       [ 0.,  2.,  0.,  0.,  0.],
       [ 1.,  1.,  3.,  0.,  0.],
       [ 1.,  1.,  0.,  3.,  0.],
       [ 1.,  1.,  0.,  0.,  3.]])

虽然主要用于块矩阵,但它适用于任意维度的数组。

它类似于 Matlab 用于创建块矩阵的方括号表示法。

isin 函数,改进了 in1d#

新函数 isin 测试 N 维数组的每个元素是否存在于第二个数组中的任何位置。它是 in1d 的增强版,可以保留第一个数组的形状。

临时变量省略#

在提供 backtrace 函数的平台上,NumPy 将尝试避免在涉及基本数值类型的表达式中创建临时变量。例如,d = a + b + c 被转换为 d = a + b; d += c,这可以提高大型数组的性能,因为执行操作所需的内存带宽更少。

unique 函数的 axes 参数#

在 N 维数组中,用户现在可以使用 numpy.unique 选择沿哪个轴查找重复的 N-1 维元素。如果 axis=None(默认),则恢复原始行为。

np.gradient 现在支持不均匀间隔数据#

用户现在可以为数据指定非恒定间隔。特别是 np.gradient 现在可以接受

  1. 单个标量,用于指定所有维度的采样距离。

  2. N 个标量,用于指定每个维度的恒定采样距离。例如 dx, dy, dz, …

  3. N 个数组,用于指定 F 各个维度上值的坐标。数组的长度必须与相应维度的大小匹配。

  4. N 个标量/数组的任意组合,其含义为 2. 和 3.

这意味着,例如,现在可以执行以下操作

>>> f = np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float_)
>>> dx = 2.
>>> y = [1., 1.5, 3.5]
>>> np.gradient(f, dx, y)
[array([[ 1. ,  1. , -0.5], [ 1. ,  1. , -0.5]]),
 array([[ 2. ,  2. ,  2. ], [ 2. ,  1.7,  0.5]])]

apply_along_axis 中支持返回任意维度的数组#

以前,传递给 apply_along_axis 的函数只能返回标量或一维数组。现在,它可以返回任意维度(包括 0 维)的数组,并且该数组的形状将替换被迭代数组的轴。

dtype 中新增 .ndim 属性以补充 .shape#

为了与 ndarraybroadcast 保持一致,d.ndimlen(d.shape) 的简写。

支持 Python 3.6 中的 tracemalloc#

NumPy 现在支持使用 Python 3.6 或更高版本中的 tracemalloc 模块进行内存跟踪。NumPy 的内存分配被放置在由 numpy.lib.tracemalloc_domain 定义的域中。请注意,NumPy 的分配在更早的 Python 版本的 tracemalloc 中不会显示。

NumPy 可以通过启用宽松步幅检查调试来构建#

在启用宽松步幅检查时,在环境中设置 NPY_RELAXED_STRIDES_DEBUG=1 将导致 NumPy 编译时将受影响的步幅设置为 npy_intp 的最大值,以帮助检测下游项目中步幅的无效使用。启用后,无效使用通常会导致错误,但错误的具体类型取决于代码细节。在实际使用中观察到 TypeError 和 OverflowError。

以前,此选项在发布版本中禁用,在主分支中启用,并且两者之间的切换需要修改代码。现在,它默认禁用,但可以为测试构建启用。

改进#

针对重叠输入的 Ufunc 行为#

在之前的 NumPy 版本中,ufunc 输入和输出操作数存在内存重叠的操作会产生未定义的结果,原因是数据依赖性问题。在 NumPy 1.13.0 中,此类操作的结果现在被定义为与没有内存重叠的等效操作相同。

受影响的操作现在会根据需要创建临时副本,以消除数据依赖性。由于检测这些情况的计算成本很高,因此使用了启发式方法,这在极少数情况下可能导致不必要的临时副本。对于数据依赖性足够简单,启发式方法可以分析的操作,即使数组重叠,如果可以推断出不需要副本,也不会创建临时副本。例如,``np.add(a, b, out=a)`` 将不涉及副本。

以说明以前未定义的操作

>>> x = np.arange(16).astype(float)
>>> np.add(x[1:], x[:-1], out=x[1:])

在 NumPy 1.13.0 中,最后一行保证等同于

>>> np.add(x[1:].copy(), x[:-1].copy(), out=x[1:])

一个具有简单无问题数据依赖性的类似操作是

>>> x = np.arange(16).astype(float)
>>> np.add(x[1:], x[:-1], out=x[:-1])

它将继续产生与之前 NumPy 版本相同的结果,并且不会涉及不必要的临时副本。

此更改也适用于就地二元操作,例如

>>> x = np.random.rand(500, 500)
>>> x += x.T

此语句现在保证等同于 x[...] = x + x.T,而在之前的 NumPy 版本中,结果是未定义的。

对 MinGW 下 64 位 f2py 扩展的部分支持#

现在可以使用免费的 MinGW 工具集构建包含 Fortran 库的扩展,该工具集也适用于 Python 3.5。这对于仅进行计算并适度使用运行时的扩展(例如,从文件读取和写入)效果最佳。请注意,这并不能消除对 Mingwpy 的需求;如果您大量使用运行时,则很可能会遇到问题。相反,这应被视为在 Mingwpy 完全可用之前的权宜之计。

扩展还可以使用 MinGW 工具集以及 (可移动的) WinPython 3.4 发行版中的运行时库进行编译,这对于具有 PySide1/Qt4 前端界面的程序可能很有用。

packbitsunpackbits 的性能改进#

具有布尔输入和 numpy.unpackbits 的函数 numpy.packbits 已经过优化,对于连续数据显著加快。

修复 PPC long double 浮点信息的问题#

在之前的 NumPy 版本中,finfo 函数返回了关于 Power PC (PPC) 上 longdouble 浮点类型的 双精度双精度 格式的无效信息。这些无效值是由于 NumPy 算法无法处理 PPC long doubles 特征中的有效数字位数可变而导致的。此版本通过使用启发式方法检测 PPC 双精度双精度格式的存在来绕过失败的算法。使用这些启发式方法的副作用是,finfo 函数比以前的版本更快。

ndarray 子类更好的默认 repr#

没有 repr 特殊化的 ndarray 子类现在可以正确缩进其数据和类型行。

蒙版数组更可靠的比较#

蒙版数组的比较对于蒙版标量存在错误,并且对于维度大于一的结构化数组会失败。这两个问题现在都已解决。在此过程中,已确保在获取结构化数组的结果时,蒙版字段被正确忽略,即如果两者中所有未被蒙版的字段都相等,则结果相等,从而使行为与比较非结构化蒙版数组然后对某个轴执行 .all() 获得的行为相同。

具有布尔元素的 np.matrix 现在可以使用字符串语法创建#

以前,当尝试将 np.matrix 与布尔值一起使用时,例如 np.matrix('True'),都会失败。现在,这按预期工作。

更多 linalg 操作现在接受空向量和矩阵#

np.linalg 中的所有以下函数现在在给定最后两个维度为 0 的输入数组时都可以工作:detslogdetpinveigvalseigvalsheigeigh

LAPACK 捆绑版本现在是 3.2.2#

NumPy 捆绑了一个名为 lapack_lite 的 lapack 最小实现,用于未安装 lapack 库的系统。此版本已从 LAPACK 3.0.0(1999 年 6 月 30 日)升级到 LAPACK 3.2.2(2010 年 6 月 30 日)。有关所有相关更改的详细信息,请参阅 LAPACK 变更日志

虽然没有通过 numpy 暴露新功能,但此版本修复了一些关于“工作空间”大小的错误,并且在某些地方可能使用更快的算法。

np.hypot.reducenp.logical_xorreduce 在更多情况下被允许#

这现在适用于空数组,返回 0,并且可以在多个轴上进行归约。以前,在这些情况下会抛出 ValueError

更好的对象数组 repr#

包含自身的对象数组不再导致递归错误。

包含 list 对象的对象数组现在以一种清晰的方式打印,以区分二维对象数组和列表的一维对象数组。

变更#

蒙版数组上的 argsort 采用与 sort 相同的默认参数#

默认情况下,argsort 现在将蒙版值放置在排序数组的末尾,与 sort 之前所做的方式相同。此外,为了与 sort 保持一致,end_with 参数已添加到 argsort。请注意,此参数并非添加到末尾,因此会破坏任何将 fill_value 作为位置参数传递的代码。

average 现在保留子类#

对于 ndarray 子类,numpy.average 现在将返回该子类的一个实例,这与大多数其他 NumPy 函数(例如 mean)的行为一致。因此,以前返回标量的调用现在也可能返回子类数组标量。

array == Nonearray != None 执行元素级比较#

以前这些操作分别返回标量 FalseTrue

对象数组的 np.equal, np.not_equal 忽略对象标识#

以前,这些函数总是将相同对象视为相等。这产生了覆盖比较失败、不返回布尔值的对象(例如 np.array)的比较以及结果与对象标识不同的对象(例如 NaN)的比较的效果。

布尔索引变更#

  • 类布尔数组(例如 Python 布尔列表)始终被视为布尔索引。

  • 布尔标量(包括 Python True)是合法的布尔索引,并且从不被视为整数。

  • 布尔索引必须与其所索引轴的维度匹配。

  • 赋值 LHS 上的布尔索引必须与 RHS 的维度匹配。

  • 对标量数组进行布尔索引会返回一个新的 1 维数组。这意味着 array(1)[array(True)] 返回 array([1]) 而不是原始数组。

np.random.multivariate_normal 在协方差矩阵不良时的行为#

现在可以通过使用两个新的关键字参数来调整函数在处理协方差矩阵时的行为

  • tol 可用于指定检查协方差矩阵是否为正半定时的容差。

  • check_valid 可用于配置函数在存在非正半定矩阵时应执行的操作。有效选项包括 ignorewarnraise。默认值 warn 保留了之前版本中的行为。

assert_array_less 现在比较 np.inf-np.inf#

以前,np.testing.assert_array_less 忽略所有无穷大值。这不符合文档和直觉中的预期行为。现在,对于任何实数 x,-inf < x < inf 被认为是 True,所有其他情况都将失败。

assert_array_ 和蒙版数组的 assert_equal 隐藏更少的警告#

以前被 assert_array_ 函数隐藏的一些警告不再被隐藏。在大多数情况下,这些警告应该是正确的,如果出现,将需要更改使用这些函数的测试。对于蒙版数组的 assert_equal 版本,在比较 NaT 时可能会出现警告。该函数目前没有专门处理 NaT 或 NaN,如果由于此更改而出现警告,最好暂时避免使用它。

memmap 对象中的 offset 属性值#

memmap 对象中的 offset 属性现在设置为文件中的偏移量。此行为仅在偏移量大于 mmap.ALLOCATIONGRANULARITY 时发生变化。

np.realnp.imag 对标量输入返回标量#

以前,当提供标量输入时,np.realnp.imag 会返回数组对象,这与 np.anglenp.conj 等其他函数不一致。

多项式便捷类不能传递给 ufuncs#

派生出便捷类的 ABCPolyBase 类将 __array_ufunc__ = None,以选择退出 ufuncs。如果将多项式便捷类实例作为参数传递给 ufunc,现在将引发 TypeError

ufuncs 的输出参数也可以是 ufunc 方法的元组#

对于 ufuncs 的调用,已经可以使用(并且推荐使用)带有元组的 out 参数用于具有多个输出的 ufuncs。现在,这已扩展到 reduceaccumulatereduceat 方法中的输出参数。这主要是为了与 __array_ufunc 兼容;目前还没有具有多个输出的 ufuncs。