NumPy 1.13.0 发行说明#
此版本支持 Python 2.7 和 3.4 - 3.6。
亮点#
在某些平台上,像
a + b + c这样的操作会重用临时变量,从而减少内存使用并加快执行速度。原地操作会检查输入是否与输出重叠,并创建临时变量以避免问题。
新的
__array_ufunc__属性提供了改进的能力,使类能够覆盖默认的 ufunc 行为。新的
np.block函数用于创建分块数组。
新增函数#
新的
np.positiveufunc。新的
np.divmodufunc 提供了更高效的 divmod。新的
np.isnatufunc 测试 NaT 特殊值。新的
np.heavisideufunc 计算 Heaviside 函数。新的
np.isin函数,改进了in1d。新的
np.block函数用于创建分块数组。向 NumPy C-API 添加了
PyArray_MapIterArrayCopyIfOverlap。
详情请参见下文。
弃用#
使用
f(x, y=out)形式调用np.fix、np.isposinf和np.isneginf已弃用 - 参数应作为f(x, out=out)传递,这与其他 ufunc 类的接口相匹配。C-API
NPY_CHAR类型编号自 1.7 版本以来已被弃用,现在将在运行时引发弃用警告。需要使用旧版 f2py 编译的扩展需要重新编译以消除警告。当应用于维度大于 2 的数组时,应使用显式的 axis 参数调用
np.ma.argsort、np.ma.minimum.reduce和np.ma.maximum.reduce,因为该参数的默认值(None)与 numpy 的其他部分(分别为-1、0和0)不一致。np.ma.MaskedArray.mini已弃用,因为它几乎复制了np.MaskedArray.min的功能。可以使用np.ma.minimum.reduce来获得完全相同的行为。单参数形式的
np.ma.minimum和np.ma.maximum已弃用。np.ma.minimum(x)现在应拼写为np.ma.minimum.reduce(x),这与使用np.minimum执行此操作的方式一致。在非数值 dtype 上调用
ndarray.conjugate已弃用(它应该与np.conjugate的行为匹配,后者会引发错误)。调用
expand_dims时,如果axis关键字不满足-a.ndim - 1 <= axis <= a.ndim(其中a是正在重塑的数组),则已弃用。
未来变化#
在 NumPy 1.14 中,具有不同字段名称的结构化数组之间的赋值将发生更改。以前,目标数组的字段将设置为源数组中同名字段的值。在 NumPy 1.14 中,字段将改为“按位置”赋值:目标数组的第 n 个字段将设置为源数组的第 n 个字段。请注意,NumPy 1.12 中引发的
FutureWarning不正确地将此更改报告为计划在 NumPy 1.13 而不是 NumPy 1.14 中进行。
构建系统更改#
numpy.distutils现在使用与 GCC 兼容的编译器自动确定 C 文件依赖关系。
兼容性说明#
错误类型更改#
当输入为空时,
numpy.hstack()现在引发ValueError而不是IndexError。接受 axis 参数的函数,当该参数超出范围时,现在引发
np.AxisError,而不是混合IndexError和ValueError。为了向后兼容,AxisError是两者的子类。
元组对象 dtypes#
已移除对某些晦涩的 dtype 的支持,这些 dtype 是无意中允许的,形式为 (old_dtype, new_dtype),其中任一 dtype 是或包含 object dtype。例外情况是,形式为 (object, [('name', object)]) 的 dtype 仍然支持,因为有现有使用的证据。
DeprecationWarning 变为错误#
有关更多详细信息,请参见“更改”部分。
partition,使用非整数分区索引时出现 TypeError。NpyIter_AdvancedNew,当oa_ndim == 0且op_axes为 NULL 时出现 ValueError。negative(bool_),将 negative 应用于布尔值时出现 TypeError。subtract(bool_, bool_),从布尔值中减去布尔值时出现 TypeError。np.equal, np.not_equal,对象标识不会覆盖失败的比较。np.equal, np.not_equal,对象标识不会覆盖非布尔比较。已删除已弃用的布尔索引行为。有关详细信息,请参见下方的“更改”。
已移除已弃用的
np.alterdot()和np.restoredot()。
FutureWarning 变为行为更改#
有关更多详细信息,请参见“更改”部分。
numpy.average保留子类array == None和array != None进行逐元素比较。np.equal, np.not_equal,对象标识不会覆盖比较结果。
dtypes 现在始终为 true#
以前 bool(dtype) 会回退到默认的 python 实现,该实现检查 len(dtype) > 0。由于 dtype 对象将 __len__ 实现为记录字段的数量,因此标量 dtype 的 bool 将评估为 False,这是不直观的。现在,所有 dtype 的 bool(dtype) == True。
__getslice__ 和 __setslice__ 在 ndarray 子类中不再需要#
在 Python 2.7 中继承 np.ndarray 时,在派生类中实现 __*slice__ 不再是 _必需_ 的,因为 __*item__ 将正确拦截这些调用。
任何实现了这些的代码将与以前一样工作。调用 ndarray.__getslice__ 的代码(例如,通过 super(...).__getslice__)现在将发出 DeprecationWarning - 应改为使用 .__getitem__(slice(start, end))。
使用 ... (省略号) 对 MaskedArrays/Constants 进行索引现在返回 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 特殊日期时间和 timedelta 值#
新的 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 函数用于创建分块数组#
在当前堆叠函数 vstack、hstack 和 stack 中添加了一个新的 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 现在可以接受:
一个标量,用于指定所有维度的采样距离。
N 个标量,用于指定每个维度的恒定采样距离。即
dx、dy、dz,……N 个数组,用于指定 F 的每个维度上的值的坐标。数组的长度必须与相应维度的尺寸匹配。
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 的函数只能返回标量或一维数组。现在,它可以返回任意维度的数组(包括 0D),并且该数组的形状会替换被迭代的数组的轴。
dtype 添加了 .ndim 属性以补充 .shape#
为了与 ndarray 和 broadcast 保持一致,d.ndim 是 len(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。
以前,此选项在发布版本中被禁用,在 master 分支中启用,并且在两者之间更改需要编辑代码。现在默认禁用它,但可以为测试构建启用它。
改进#
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 工具集,在 Python 3.5 下,使用包含 Fortran 库的扩展。这对于只进行计算且运行时使用适度的扩展(例如,读写文件)效果最好。请注意,这并没有消除对 Mingwpy 的需求;如果您大量使用运行时,您很可能会遇到 问题。相反,它应该被视为 Mingwpy 完全正常运行前的临时解决方案。
扩展程序也可以使用(可移动的)WinPython 3.4 分发版的运行时库,使用 MinGW 工具集进行编译,这对于具有 PySide1/Qt4 前端的程序可能很有用。
对 packbits 和 unpackbits 的性能改进#
函数 numpy.packbits(使用布尔输入)和 numpy.unpackbits 已得到优化,对于连续数据来说速度显著更快。
修复 PPC 长双精度浮点信息#
在以前版本的 NumPy 中,finfo 函数返回了关于 Power PC (PPC) 上的 longdouble 浮点类型的 双倍精度 格式的无效信息。无效值源于 NumPy 算法未能处理 PPC 长双精度 中的尾数位数可变 的特征。此版本通过使用启发式方法检测 PPC 双倍精度格式的存在,来绕过失败的算法。使用这些启发式方法的副作用是 finfo 函数比以前的版本更快。
对 ndarray 子类更好的默认 repr#
没有 repr 特殊化的 ndarray 子类现在会正确缩进其数据和类型行。
对掩码数组的比较更可靠#
掩码数组的比较对于掩码标量存在错误,并且对于维度大于一的结构化数组失败。这两个问题现在都已解决。在此过程中,已确保在获取结构化数组的结果时,掩码字段会被正确忽略,即,如果两个数组中所有非掩码字段都相等,则结果相等,从而使行为与通过比较非结构化掩码数组然后对某个轴执行 .all() 所获得的行为相同。
现在可以使用字符串语法创建具有布尔元素的 np.matrix#
np.matrix 在尝试使用布尔值时失败,例如 np.matrix('True')。现在,这如预期工作。
更多的 linalg 操作现在接受空向量和空矩阵#
以下 np.linalg 中的所有函数现在都可以在给定最后一个维度为 0 的输入数组时工作:det、slogdet、pinv、eigvals、eigvalsh、eig、eigh。
捆绑的 LAPACK 版本现为 3.2.2#
NumPy 捆绑了 lapack 的最小实现,用于没有 lapack 库的系统,名称为 lapack_lite。该库已从 LAPACK 3.0.0(1999 年 6 月 30 日)升级到 LAPACK 3.2.2(2010 年 6 月 30 日)。有关所有这些更改的详细信息,请参阅 LAPACK 发行说明。
虽然 numpy 没有暴露任何新功能,但这修复了与“工作区”大小相关的一些错误,并在某些地方可能使用了更快的算法。
np.hypot.reduce 和 np.logical_xor 的 reduce 在更多情况下被允许#
现在,这可以在空数组上工作,返回 0,并且可以对多个轴进行规约。以前,在这些情况下会引发 ValueError。
对象数组的更好的 repr#
包含自身的对对象数组现在不再导致递归错误。
包含 list 对象的对对象数组现在以一种清晰区分 2D 对象数组和列表的 1D 对象数组的方式打印。
更改#
对掩码数组的 argsort 与 sort 具有相同的默认参数#
默认情况下,argsort 现在将掩码值放在排序数组的末尾,与 sort 已经做的一样。此外,为 argsort 添加了 end_with 参数,以与 sort 保持一致。请注意,此参数不是放在最后,因此会破坏任何将 fill_value 作为位置参数传递的代码。
average 现在保留子类#
对于 ndarray 子类,numpy.average 现在将返回子类的一个实例,与大多数其他 NumPy 函数(如 mean)的行为相匹配。因此,之前返回标量的调用现在可能返回子类数组标量。
array == None 和 array != None 进行逐元素比较#
以前,这些操作分别返回标量 False 和 True。
对象数组的 np.equal, np.not_equal 忽略对象标识#
以前,这些函数总是将相同的对象视为相等。这会覆盖比较失败、不返回布尔值的对象的比较(例如 np.arrays)以及结果与对象标识不同的对象的比较(例如 NaN)。
布尔索引更改#
布尔类数组(如 Python 布尔值的列表)始终被视为布尔索引。
布尔标量(包括 Python
True)是合法的布尔索引,从不被视为整数。布尔索引必须匹配其索引的轴的维度。
用于赋值左侧的布尔索引必须匹配右侧的维度。
对标量数组进行布尔索引会返回一个新的一维数组。这意味着
array(1)[array(True)]的结果是array([1])而不是原始数组。
np.random.multivariate_normal 对无效协方差矩阵的行为#
现在可以使用两个新的关键字参数来调整函数在处理协方差矩阵时的行为:
tol可用于指定在检查协方差矩阵是否为半正定时使用的容差。check_valid可用于配置函数在存在非半正定矩阵时的行为。有效选项为ignore、warn和raise。默认值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.real 和 np.imag 对标量输入返回标量#
以前,当提供标量输入时,np.real 和 np.imag 会返回数组对象,这与 np.angle 和 np.conj 等其他函数不一致。
多项式便捷类不能传递给 ufuncs#
ABCPolyBase 类(便捷类由此派生)设置为 __array_ufun__ = None 以选择退出 ufuncs。如果多项式便捷类的实例作为 ufunc 的参数传递,现在将引发 TypeError。
ufunc 的输出参数也可以是元组,ufunc 方法也一样#
对于 ufuncs 的调用,已经可以使用(并且推荐)带有元组的 `out` 参数来处理具有多个输出的 ufuncs。现在,此功能已扩展到 `reduce`、`accumulate` 和 `reduceat` 方法中的输出参数。这主要是为了与 `__array_ufunc__` 兼容;目前还没有具有多个输出的 ufuncs。