NumPy 1.15.0 发行说明#
NumPy 1.15.0 版本发布带来了大量清理工作,许多旧函数被弃用,并且对许多现有函数进行了改进.请阅读下面的详细说明,以查看您是否受到影响.
在测试方面,我们已切换到 pytest 以替代不再维护的 nose 框架.旧的基于 nose 的接口仍然保留,以供可能仍在使用的下游项目使用.
此版本支持的 Python 版本为 2.7,3.4-3.7.这些 wheels 链接了 OpenBLAS v0.3.0,应该可以修复 NumPy 1.14 报告的一些 linalg 问题.
亮点#
NumPy 已切换到 pytest 进行测试.
一个新的
numpy.printoptions上下文管理器.直方图函数的许多改进.
在 python 2.7 中支持 unicode 字段名称.
改进了对 PyPy 的支持.
修复和改进了
numpy.einsum.
新函数#
numpy.ma.stack,numpy.stack数组连接函数已推广到 masked arrays.numpy.quantile函数,一个没有 100 倍因子的percentile接口.numpy.nanquantile函数,一个没有 100 倍因子的nanpercentile接口.numpy.printoptions,一个上下文管理器,用于在with块的范围内临时设置打印选项:>>> with np.printoptions(precision=2): ... print(np.array([2.0]) / 3) [0.67]
numpy.histogram_bin_edges,一个用于获取直方图使用的 bin 边缘的函数,而无需计算直方图.C 函数 npy_get_floatstatus_barrier 和 npy_clear_floatstatus_barrier 已被添加,以处理编译器优化更改操作顺序的情况. 详见下文.
弃用#
内置
pickle函数的别名已被弃用,建议使用其未设置别名的pickle.<func>名称:numpy.loads
numpy.core.numeric.load
numpy.core.numeric.loads
numpy.ma.loads , numpy.ma.dumps
numpy.ma.load , numpy.ma.dump - 这些函数在使用字符串调用时已在 python 3 上失败.
使用元组以外的任何东西进行多维索引已被弃用. 这意味着
ind = [slice(None), 0]; arr[ind]中的索引列表应更改为元组,例如ind = [slice(None), 0]; arr[tuple(ind)]或arr[(slice(None), 0)]. 这种更改是必要的,以避免在诸如arr[[[0, 1], [0, 1]]]之类的表达式中出现歧义,当前解释为arr[array([0, 1]), array([0, 1])],将来将被解释为arr[array([[0, 1], [0, 1]])].来自以下子模块的导入已被弃用,它们将在将来的某个日期被删除.
numpy.testing.utils
numpy.testing.decorators
numpy.testing.nosetester
numpy.testing.noseclasses
numpy.core.umath_tests
现在不建议将生成器提供给
numpy.sum. 这是未记录的行为,但有效. 之前,它会计算生成器表达式的总和. 将来,它可能会返回不同的结果. 请改用np.sum(np.from_iter(generator))或内置的 Pythonsum.C-API 的用户应该在释放数组之前,对任何设置了
WRITEBACKIFCOPY标志的数组调用PyArrayResolveWriteBackIfCopy或PyArray_DiscardWritebackIfCopy. 如果在需要时未使用这些调用,则会发出弃用警告.nditer的使用者应该将 nditer 对象用作上下文管理器,当迭代器操作数是可写的时,这样 numpy 才能管理写回语义,或者应该调用it.close().否则,在这些情况下可能会发出 RuntimeWarning .np.histogram的normed参数在 1.6.0 中早已被弃用,现在会发出DeprecationWarning.
未来的变化#
NumPy 1.16 将不再支持 Python 3.4.
NumPy 1.17 将不再支持 Python 2.7.
兼容性说明#
编译的测试模块已重命名并设为私有#
以下编译的模块已重命名并设为私有:
umath_tests->_umath_teststest_rational->_rational_testsmultiarray_tests->_multiarray_testsstruct_ufunc_test->_struct_ufunc_testsoperand_flag_tests->_operand_flag_tests
为了向后兼容, umath_tests 模块仍然可用,但将来会被删除.
由 np.savez 返回的 NpzFile 现在是一个 collections.abc.Mapping#
这意味着它的行为类似于只读字典,并且有一个新的 .values() 方法和 len() 实现.
对于 python 3,这意味着 .iteritems() , .iterkeys() 已被弃用,并且 .keys() 和 .items() 现在返回视图而不是列表.这与内置 dict 类型在 python 2 和 python 3 之间的变化是一致的.
在某些情况下, nditer 必须在上下文管理器中使用#
当使用带有 "writeonly" 或 "readwrite" 标志的 numpy.nditer 时,在某些情况下,nditer 实际上并没有给你一个可写数组的视图.而是给你一个副本,如果你修改了副本,nditer 稍后会将这些更改写回到你的实际数组中.目前,当数组对象被垃圾回收时,会发生这种写回,这使得这个 API 在 CPython 上容易出错,并且在 PyPy 上完全损坏.因此,只要 nditer 与可写数组一起使用,就应该将其用作上下文管理器,例如, with np.nditer(...) as it: ... .对于无法使用上下文管理器的情况(例如在生成器表达式中),你也可以显式调用 it.close() .
Numpy 已经切换到使用 pytest 而不是 nose 进行测试#
上一个 nose 版本是 2015 年 6 月的 1.3.7,并且该工具的开发已经结束,因此 NumPy 现在已经切换到使用 pytest.以前被一些下游项目使用的旧装饰器和 nose 工具仍然可用,但不会被维护.标准测试实用程序,例如 assert_almost_equal 等,不会受到此更改的影响,除了 nose 特定的函数 import_nose 和 raises .这些函数没有在 numpy 中使用,但为了下游兼容性而保留.
Numpy 不再使用 __array_interface__ monkey-patches ctypes#
以前,numpy 将 __array_interface__ 属性添加到 ctypes 中的所有整数类型.
np.ma.notmasked_contiguous 和 np.ma.flatnotmasked_contiguous 总是返回列表#
这是文档中说明的行为,但以前结果可以是切片,None 或列表中的任何一个.
所有下游用户似乎都在检查来自 flatnotmasked_contiguous 的 None 结果并将其替换为 [] .这些调用者将继续像以前一样工作.
np.squeeze 恢复了无法处理 axis 参数的对象的旧行为#
在版本 1.7.0 之前, numpy.squeeze 没有 axis 参数,默认情况下会删除所有空轴.合并 axis 参数使得可以选择性地挤压单个或多个空轴,但是旧的 API 期望没有得到尊重,因为仍然可以从期望删除所有空轴的对象中选择性地删除轴(静默成功).对于期望旧行为的对象,静默地选择性删除空轴已被修复,并且旧行为已恢复.
非结构化 void 数组的 .item 方法现在返回一个 bytes 对象#
.item 现在返回一个 bytes 对象,而不是 buffer 或 byte array.这可能会影响假定返回值是可变的代码,但现在情况已非如此.
copy.copy 和 copy.deepcopy 不再将 masked 转换为数组#
由于 np.ma.masked 是一个只读标量,复制应该是一个空操作.这些函数的行为现在与 np.copy() 一致.
结构化数组的多字段索引仍然返回一个副本#
结构化数组的多字段索引返回视图而不是副本的更改推迟到 1.16.引入了一个新的方法 numpy.lib.recfunctions.repack_fields 来帮助缓解此更改的影响,该方法可用于编写与 numpy 1.15 和 1.16 兼容的代码.有关如何更新代码以适应未来更改的更多信息,请参阅 user guide 的 “accessing multiple fields” 部分.
C API 更改#
新的函数 npy_get_floatstatus_barrier 和 npy_clear_floatstatus_barrier#
添加了函数 npy_get_floatstatus_barrier 和 npy_clear_floatstatus_barrier ,应该用来代替 npy_get_floatstatus 和 npy_clear_status 函数.像 GCC 8.1 和 Clang 这样的优化编译器在使用 ufunc SIMD 函数中的前一个函数时,会重新排列操作的顺序,导致在运行我们想要检查其状态的操作之前检查 floatstatus 标志.参见 #10339 .
PyArray_GetDTypeTransferFunction 的变化#
PyArray_GetDTypeTransferFunction 现在默认为用户定义的 dtype 使用用户定义的 copyswapn / copyswap .如果这导致显著的性能下降,请考虑实现 copyswapn 以反映 PyArray_GetStridedCopyFn 的实现.参见 #10898 .
新特性#
为整数和对象类型添加了 np.gcd 和 np.lcm ufuncs#
这些分别计算最大公约数和最小公倍数.这些适用于所有 numpy 整数类型,以及内置的任意精度 Decimal 和 long 类型.
支持 iOS 的跨平台构建#
构建系统已经过修改,以添加对 _PYTHON_HOST_PLATFORM 环境变量的支持,该变量在为一个平台编译到另一个平台时被 distutils 使用.这使得为 iOS 目标编译 NumPy 成为可能.
这只允许你一次为一个特定的平台编译 NumPy.创建一个完整的 iOS 兼容的 NumPy 包需要为 iOS 支持的 5 个架构(i386,x86_64,armv7,armv7s 和 arm64)构建,并将这 5 个编译的构建产品合并成一个“胖”二进制文件.
为 np.intersect1d 添加了 return_indices 关键字#
新的关键字 return_indices 返回与公共元素对应的两个输入数组的索引.
np.quantile 和 np.nanquantile#
与 np.percentile 和 np.nanpercentile 类似,但接受 [0, 1] 中的分位数,而不是 [0, 100] 中的百分位数. np.percentile 现在是 np.quantile 的一个薄包装器,增加了除以 100 的额外步骤.
构建系统#
增加了对 64 位 RISC-V 架构的实验性支持.
改进#
np.einsum 更新#
同步了 numpy 和 opt_einsum 之间的 einsum 路径优化技术.特别是, greedy 路径已经收到了 @jcmgray 的许多增强.已修复问题的完整列表为:
任意内存可以传递到 greedy 路径中.修复了 gh-11210.
greedy 路径已经更新,包含了更多的动态编程思想,防止了大量重复的(且昂贵的)调用,这些调用用于计算实际发生的配对收缩.现在可以在数百个输入张量上运行几秒钟.对矩阵乘积态理论很有用.
重构了 gh-11218 gh-10352 中发现的广播点积错误捕获,使其在流程中更早地进行.
增强了 can_dot 功能,该功能之前错过了一个边缘情况(gh-11308 的一部分).
np.flip 可以在多个轴上操作#
np.flip 现在接受 None,或 int 元组作为其 axis 参数.如果 axis 为 None,它将翻转所有轴.
histogram 和 histogramdd 函数已移动到 np.lib.histograms#
这些函数最初位于 np.lib.function_base 中. 它们仍然可以在未限定范围的 np.histogram(dd) 名称下使用,并且为了保持兼容性,在 np.lib.function_base.histogram(dd) 处进行了别名.
执行 from np.lib.function_base import * 的代码需要使用新位置进行更新,并且应考虑将来不使用 import * .
当给出显式 bin 时, histogram 将接受 NaN 值#
以前,当尝试计算数据的有限范围时,它将失败.由于当显式给出 bin 时会忽略该范围,因此该错误是不必要的.
请注意,在 NaN 值上调用 histogram 会继续引发使用 nan 值的典型 RuntimeWarning ,可以使用 errstate 像往常一样将其静音.
当给出显式 bin 边缘时, histogram 可用于 datetime 类型#
现在可以对日期,时间和时间差进行直方图化.必须显式传递 bin 边缘,并且尚未自动计算.
histogram “auto”估计器更好地处理有限方差#
IQR 为 0 不再导致 n_bins=1 ,而是,在这种情况下,所选的 bin 数量与数据大小相关.
histogram 和 histogramdd 返回的 edges 现在与数据 float 类型匹配#
当传递 np.float16 , np.float32 或 np.longdouble 数据时,返回的 edges 现在具有相同的数据类型.以前,只有在给出显式 bin 时, histogram 才会返回相同的类型,并且无论输入是什么, histogram 都会生成 float64 bin.
histogramdd 允许在轴的子集中给出显式范围#
numpy.histogramdd 的 range 参数现在可以包含 None 值,以指示应从数据中计算相应轴的范围. 以前,不能按轴指定此参数.
histogramdd 和 histogram2d 的 normed 参数已重命名#
这些参数现在称为 density ,这与 histogram 一致.旧的参数继续有效,但应首选新名称.
np.r_ 可以与 0d 数组一起使用, np.ma.mr_ 可以与 np.ma.masked 一起使用#
传递给 r_ 和 mr_ 连接助手的 0d 数组现在被视为长度为 1 的数组.以前,传递这些数组会出错.因此, numpy.ma.mr_ 现在可以正确地处理 masked 常量.
np.ptp 接受一个 keepdims 参数,并扩展了轴元组#
np.ptp (峰峰值) 现在可以像 np.max 和 np.min 一样,在多个轴上工作.
MaskedArray.astype 现在与 ndarray.astype 相同#
这意味着它接受所有相同的参数,使为 ndarray 编写的更多代码也可以用于 masked array.
在编译时启用 AVX2/AVX512#
更改为 simd.inc.src 以允许在编译时使用 AVX2 或 AVX512. 以前,即使代码的其余部分获得了 AVX2,使用 -march=native 编译 avx2(或 512)仍然会对 simd 函数使用 SSE 代码.
nan_to_num 在接收标量或 0d 输入时始终返回标量#
以前,对于整数标量输入,会返回一个数组,这与浮点输入的行为以及 ufuncs 的一般行为不一致. 对于所有类型的标量或 0d 输入,结果现在都是标量.
np.flatnonzero 适用于 numpy 可转换类型#
np.flatnonzero 现在使用 np.ravel(a) 而不是 a.ravel() ,因此它适用于列表,元组等.
np.interp 返回 numpy 标量而不是内置标量#
以前, np.interp(0.5, [0, 1], [10, 20]) 会返回一个 float ,但现在它返回一个 np.float64 对象,这更符合其他函数的行为.
此外,不再支持 np.interp(object_array_0d, ...) 的特殊情况,因为无论如何都不支持 np.interp(object_array_nd) .
由于此更改, period 参数现在可以用于 0d 数组.
允许 dtype 字段名称在 Python 2 中为 unicode#
以前, np.dtype([(u'name', float)]) 会在 Python 2 中引发 TypeError ,因为只有字节字符串才允许在字段名称中使用. 现在,任何 unicode 字符串字段名称都将使用 ascii 编解码器进行编码,并在失败时引发 UnicodeEncodeError .
此更改使使用 from __future__ import unicode_literals 编写 Python 2/3 兼容代码更容易,这以前会导致字符串字面量字段名称在 Python 2 中引发 TypeError.
比较 ufuncs 接受 dtype=object ,覆盖默认的 bool#
这允许符号类型的对象数组(它覆盖 == 和其他运算符以返回表达式)与 np.equal(a, b, dtype=object) 进行元素级比较.
sort 函数接受 kind='stable'#
到目前为止,要在数据上执行稳定排序,用户必须执行以下操作:
>>> np.sort([5, 2, 6, 2, 1], kind='mergesort')
[1, 2, 2, 5, 6]
因为归并排序是 NumPy 中唯一可用的稳定排序算法. 但是,拥有 kind=’mergesort’ 并不能明确用户想要执行稳定排序,从而损害了可读性.
此更改允许用户指定 kind=’stable’,从而阐明意图.
不要为就地累积创建临时副本#
当 ufuncs 执行累积时,它们不再由于输入和输出之间的重叠而创建临时副本,也就是说,下一个累积的元素在累积结果存储在其位置之前添加,因此重叠是安全的. 避免复制可以加快执行速度.
linalg.matrix_power 现在可以处理矩阵堆栈#
与 linalg 中的其他函数一样, matrix_power 现在可以处理大于 2 的数组维度,这些数组被视为矩阵堆栈. 作为更改的一部分,为了进一步提高一致性,第一个参数的名称已更改为 a (从 M ),并且非方形矩阵的异常已更改为 LinAlgError (从 ValueError ).
提升了多维数组在 random.permutation 中的性能#
permutation 在 random.shuffle 中对所有输入数组维度使用快速路径.以前,快速路径仅用于一维数组.
广义ufunc现在接受 axes , axis 和 keepdims 参数#
可以通过传入 axes 参数来控制广义ufunc在哪些轴上运行, axes 参数是包含特定轴索引的元组列表. 例如,对于适用于矩阵乘法的 (i,j),(j,k)->(i,k) 签名,基本元素是二维矩阵,并且假定这些矩阵存储在每个参数的最后两个轴中. 对应的axes关键字是 [(-2, -1), (-2, -1), (-2, -1)] . 如果想改用前导维度,则传入 [(0, 1), (0, 1), (0, 1)] .
为简单起见,对于作用于一维数组(向量)的广义ufunc,接受单个整数而不是单元素元组;对于所有输出都是标量的广义ufunc,可以省略(空)输出元组. 因此,对于适用于内积的 (i),(i)->() 签名,可以传入 axes=[0, 0] 以指示向量存储在两个输入参数的第一个维度中.
作为类似于归约的广义ufunc的快捷方式,即在单个共享核心维度上运行(例如上面的内积示例),可以传递一个 axis 参数. 这等效于对具有该核心维度的所有参数传入具有相同条目的 axes (例如,对于上面的示例, axes=[(axis,), (axis,)] ).
此外,与归约类似,对于输入都具有相同数量的核心维度且输出没有核心维度的广义ufunc,可以传入 keepdims 以在输出中保留大小为1的维度,从而允许与原始输入正确广播. 可以使用 axes 控制额外维度的位置. 例如,对于内积示例, keepdims=True, axes=[-2, -2, -2] 将对内积示例起作用, keepdims=True, axis=-2 将对输入参数的倒数第二个维度起作用,并在输出中的相应位置保留大小为1的维度.
float128 值现在可以在 ppc 系统上正确打印#
以前,在ppc上打印float128值是有问题的,因为没有考虑到这些系统上的特殊双精度浮点格式. float128 现在以正确的舍入和唯一性打印.
PPC 用户警告:如果 glibc 版本 <=2.23,您应该升级 glibc,尤其是在使用 float128 时. 在ppc上,这些版本中的glibc的malloc经常错误地对齐分配的内存,这在使用float128值时可能会导致numpy崩溃.
新的 np.take_along_axis 和 np.put_along_axis 函数#
当在多维数组上使用时, argsort , argmin , argmax 和 argpartition 返回的数组难以用作索引. take_along_axis 提供了一种使用这些索引查找数组中值的简便方法,因此:
np.take_along_axis(a, np.argsort(a, axis=axis), axis=axis)
与以下代码相同:
np.sort(a, axis=axis)
np.put_along_axis 充当在数组中写入这些索引的双重运算.