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。
详情请见下文。
弃用#
使用
f(x, y=out)
调用np.fix
、np.isposinf
和np.isneginf
已弃用 - 参数应作为f(x, out=out)
传递,这与其他类似 ufunc 的接口匹配。自 1.7 版以来弃用的 C-API
NPY_CHAR
类型编号现在将在运行时引发弃用警告。 使用旧版 f2py 版本构建的扩展需要重新编译才能消除警告。np.ma.argsort
、np.ma.minimum.reduce
和np.ma.maximum.reduce
应用于超过 2 维的数组时,应使用显式的 axis 参数调用,因为此参数的默认值 (None
) 与其余的 numpy (-1
、0
和0
) 不一致。np.ma.MaskedArray.mini
已弃用,因为它几乎重复了np.MaskedArray.min
的功能。可以使用np.ma.minimum.reduce
获得完全等效的行为。np.ma.minimum
和np.ma.maximum
的单参数形式已弃用。np.maximum
。np.ma.minimum(x)
现在应写成np.ma.minimum.reduce(x)
,这与使用np.minimum
的方式一致。在非数值 dtype 上调用
ndarray.conjugate
已弃用(它应该与np.conjugate
的行为匹配,后者会抛出错误)。当
axis
关键字不满足-a.ndim - 1 <= axis <= a.ndim
时调用expand_dims
已弃用,其中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
是这两个类的子类。
元组对象 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
,对象标识符不会覆盖比较结果。
dtype 现在始终为真#
以前,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 更改#
空数组上的 GUfunc 和 NpyIter 轴移除#
现在允许从 NpyIter 中移除零大小的轴。 这可能意味着从 NpyIter 中移除轴的代码必须在以后访问已移除的维度时添加额外的检查。
最大的后续更改是现在允许 gufunc 具有零大小的内部维度。这意味着 gufunc 现在必须预期空内部维度,而这以前是不可能的,并且会引发错误。
对于大多数 gufunc,无需进行任何更改。但是,现在对于签名类似于 (..., N, M) -> (..., M)
的 gufunc,即使 N=0
,也可以返回有效结果,无需额外的包装代码。
NumPy C-API 中添加了 PyArray_MapIterArrayCopyIfOverlap
#
类似于 PyArray_MapIterArray
,但是增加了一个 copy_if_overlap
参数。如果 copy_if_overlap != 0
,则检查输入是否与任何其他数组存在内存重叠,并在必要时进行复制,以避免在迭代期间修改输入时出现问题。请参阅文档以获取更完整的文档。
新增功能#
添加了 __array_ufunc__
#
这是重命名并重新设计的 __numpy_ufunc__
。任何类(ndarray 子类或非子类)都可以定义此方法或将其设置为 None
以覆盖 NumPy 的 ufunc 的行为。这与 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
查找日期时间和时间增量数组中 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
,这可以提高大型数组的性能,因为执行运算所需的内存带宽更少。
axes
参数用于 unique
#
在 N 维数组中,用户现在可以使用 numpy.unique
选择查找重复 N-1 维元素的轴。如果 axis=None
(默认值),则恢复原始行为。
np.gradient
现在支持不均匀间隔的数据#
用户现在可以为数据指定非恒定间距。特别是 np.gradient
现在可以采用:
单个标量,为所有维度指定样本距离。
N 个标量,为每个维度指定恒定的样本距离,即
dx
、dy
、dz
……N 个数组,用于指定 F 的每个维度上值的坐标。数组的长度必须与相应维度的尺寸匹配。
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。
以前,此选项在发行版中被禁用,在主分支中启用,两者之间的切换需要编辑代码。现在默认情况下禁用,但可以为测试构建启用。
改进#
重叠输入的 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 完全可用。
还可以使用来自(可移动的)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
特化的 ndarray
子类现在可以正确缩进其数据和类型行。
更可靠的掩码数组比较#
掩码数组的比较对于掩码标量存在错误,对于维度高于一的结构化数组则会失败。这两个问题现在都已解决。在此过程中,我们确保在获取结构化数组的结果时,正确忽略掩码字段,即,如果两个数组中所有未掩码的字段都相等,则结果相等,从而使行为与比较非结构化掩码数组然后对某个轴进行 .all()
操作得到的结果相同。
现在可以使用字符串语法创建包含布尔元素的 np.matrix
#
当尝试使用布尔值(例如 np.matrix('True')
)时,np.matrix
会失败。现在,此功能按预期工作。
更多 linalg
操作现在接受空向量和矩阵#
以下 np.linalg
中的所有函数现在都可以处理最后两个维度为 0 的输入数组:det
、slogdet
、pinv
、eigvals
、eigvalsh
、eig
、eigh
。
捆绑的 LAPACK 版本现在是 3.2.2#
对于未安装 lapack 库的系统,NumPy 捆绑了一个名为 lapack_lite
的 lapack 最小实现。此实现已从 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
对象的数组对象现在的打印方式可以清楚地区分二维数组对象和一维列表数组对象。
更改#
掩码数组上的 argsort
使用与 sort
相同的默认参数#
默认情况下,argsort
现在将掩码值放置在已排序数组的末尾,与 sort
的方式相同。此外,为了与 sort
保持一致,end_with
参数已添加到 argsort
中。请注意,此参数不是添加到末尾的,因此会破坏将 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
)是合法的布尔索引,绝不被视为整数。布尔索引必须与其索引的轴的维度匹配。
用于赋值左侧的布尔索引必须与右侧的维度匹配。
对标量数组进行布尔索引将返回一个新的 1 维数组。这意味着
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
)不一致。
多项式便捷类无法传递给ufunc#
便捷类所继承的ABCPolyBase类,为了避免ufunc,设置了__array_ufun__ = None
。如果将多项式便捷类实例作为参数传递给ufunc,现在将引发TypeError
。
ufunc的输出参数也可以是元组,对于ufunc方法也是如此#
对于ufunc的调用,使用带有元组的out
参数(对于具有多个输出的ufunc)已经成为可能,并且是推荐的做法。现在,这已扩展到reduce
、accumulate
和reduceat
方法中的输出参数。这主要是为了与__array_ufunc__
兼容;目前还没有ufunc具有多个输出。