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.gcdnumpy.lcm ,用于计算最大公约数和最小公倍数.

  • numpy.ma.stack ,推广到掩码数组的 numpy.stack 数组连接函数.

  • 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_barriernpy_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)) 或内置的 Python sum .

  • C-API 的用户应该在任何设置了 WRITEBACKIFCOPY 标志的数组上调用 PyArrayResolveWriteBackIfCopyPyArray_DiscardWritebackIfCopy ,然后再释放该数组.如果需要时未使用这些调用,则会发出弃用警告.

  • nditer 的用户应将 nditer 对象用作上下文管理器,只要其中一个迭代器操作数是可写的,以便 numpy 可以管理写回语义,否则应调用 it.close() .在这些情况下否则可能会发出 RuntimeWarning .

  • 很久以前在 1.6.0 中已弃用的 np.histogramnormed 参数现在发出 DeprecationWarning .

未来变化#

  • NumPy 1.16 将放弃对 Python 3.4 的支持.

  • NumPy 1.17 将放弃对 Python 2.7 的支持.

兼容性说明#

已重命名并设为私有的已编译测试模块#

以下已编译的模块已重命名并设为私有:

  • umath_tests -> _umath_tests

  • test_rational -> _rational_tests

  • multiarray_tests -> _multiarray_tests

  • struct_ufunc_test -> _struct_ufunc_tests

  • operand_flag_tests -> _operand_flag_tests

umath_tests 模块仍然可用于向后兼容,但将来将被删除.

np.savez 返回的 NpzFile 现在是 collections.abc.Mapping#

这意味着它的行为类似于只读字典,并且具有新的 .values() 方法和 len() 实现.

对于 python 3,这意味着 .iteritems() , .iterkeys() 已被弃用,并且 .keys().items() 现在返回视图而不是列表.这与 python 2 和 python 3 之间内置 dict 类型的更改方式一致.

在某些情况下, 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_noseraises .这些函数在 numpy 中未使用,但为了下游兼容性而保留.

Numpy 不再使用 __array_interface__ctypes 进行猴子补丁#

以前 numpy 将 __array_interface__ 属性添加到来自 ctypes 的所有整数类型.

np.ma.notmasked_contiguousnp.ma.flatnotmasked_contiguous 总是返回列表#

这是文档化的行为,但以前结果可以是 slice,None 或 list 中的任何一个.

所有下游用户似乎都会检查来自 flatnotmasked_contiguousNone 结果,并将其替换为 [] .这些调用者将继续像以前一样工作.

np.squeeze 恢复了无法处理 axis 参数的对象的旧行为#

在版本 1.7.0 之前, numpy.squeeze 没有 axis 参数,默认情况下会删除所有空轴.合并 axis 参数使得可以选择性地压缩单个或多个空轴成为可能,但旧的 API 预期未得到尊重,因为仍然可以从期望删除所有空轴的对象中选择性地删除轴(静默成功).对于期望旧行为的对象,这种对空轴的静默,选择性删除已被修复,旧行为已恢复.

非结构化 void 数组的 .item 方法现在返回一个 bytes 对象#

.item 现在返回一个 bytes 对象,而不是一个 buffer 或 byte array.这可能会影响假定返回值是可变的代码,但现在情况并非如此.

copy.copycopy.deepcopy 不再将 masked 转换为数组#

由于 np.ma.masked 是一个只读标量,因此复制应该是一个空操作.这些函数现在的行为与 np.copy() 一致.

结构化数组的多字段索引仍然会返回一个副本#

结构化数组的多字段索引返回视图而不是副本的更改已推迟到 1.16.引入了一个新方法 numpy.lib.recfunctions.repack_fields 来帮助减轻此更改的影响,该方法可用于编写与 numpy 1.15 和 1.16 兼容的代码.有关如何更新代码以解决此未来更改的更多信息,请参见 user guide 的"访问多个字段"部分.

C API 变更#

新函数 npy_get_floatstatus_barriernpy_clear_floatstatus_barrier#

添加了函数 npy_get_floatstatus_barriernpy_clear_floatstatus_barrier ,应该使用它们来代替 npy_get_floatstatusnpy_clear_status 函数.像 GCC 8.1 和 Clang 这样的优化编译器在 ufunc SIMD 函数中使用之前的函数时,会重新排列操作的顺序,导致在运行我们想要检查其状态的操作之前检查 floatstatus 标志.参见 #10339 .

更改 PyArray_GetDTypeTransferFunction#

PyArray_GetDTypeTransferFunction 现在默认为用户定义的 dtype 使用用户定义的 copyswapn / copyswap .如果这导致显著的性能下降,请考虑实现 copyswapn 以反映 PyArray_GetStridedCopyFn 的实现.参见 #10898 .

新特性#

为整数和对象类型添加了 np.gcdnp.lcm ufuncs#

这些分别计算最大公约数和最小公倍数.这些适用于所有 numpy 整数类型,以及内置的任意精度 Decimallong 类型.

支持 iOS 的跨平台构建#

构建系统已修改为添加对 _PYTHON_HOST_PLATFORM 环境变量的支持,该变量在为一个平台编译到另一个平台时由 distutils 使用.这使得为 iOS 目标编译 NumPy 成为可能.

这仅能让你一次为一个特定平台编译 NumPy.要创建一个完全兼容 iOS 的 NumPy 包,需要为 iOS 支持的 5 种架构(i386,x86_64,armv7,armv7s 和 arm64)构建,并将这 5 个编译后的构建产品组合成一个单一的 “fat” 二进制文件.

np.intersect1d 添加了 return_indices 关键字#

新的关键字 return_indices 返回与公共元素对应的两个输入数组的索引.

np.quantilenp.nanquantile#

类似于 np.percentilenp.nanpercentile ,但接受 [0, 1] 中的分位数,而不是 [0, 100] 中的百分位数. np.percentile 现在是 np.quantile 的一个薄包装器,额外步骤是除以 100.

构建系统#

增加了对 64 位 RISC-V 架构的实验性支持.

改进#

np.einsum 更新#

同步 numpyopt_einsum 之间的 einsum 路径优化技术.特别是, greedy 路径已收到 @jcmgray 的许多增强功能.修复的完整问题列表是:

  • 可以将任意内存传递到 greedy 路径中.修复了 gh-11210.

  • 贪婪路径已更新为包含更多动态编程思想,从而防止大量重复(且代价高昂)的调用,从而确定实际发生的对收缩.现在在几百个输入张量上花费几秒钟.对矩阵乘积状态理论很有用.

  • 重新设计了 gh-11218 gh-10352 中发现的广播点错误捕获,使其在过程中更早一些.

  • 增强了 can_dot 功能,该功能先前遗漏了一个边缘情况(gh-11308 的一部分).

np.flip 可以跨多个轴操作#

np.flip 现在在其 axis 参数中接受 None 或 int 元组.如果 axis 为 None,它将翻转所有轴.

histogramhistogramdd 函数已移动到 np.lib.histograms#

这些最初是在 np.lib.function_base 中找到的.它们仍然可以在未作用域的 np.histogram(dd) 名称下使用,并且为了保持兼容性,在 np.lib.function_base.histogram(dd) 处别名.

执行 from np.lib.function_base import * 的代码将需要使用新位置进行更新,并且应考虑将来不要使用 import * .

当给出显式 bins 时, histogram 将接受 NaN 值#

以前,当尝试计算数据的有限范围时,它会失败.由于在显式给出 bins 时无论如何都会忽略该范围,因此该错误是不必要的.

请注意,对 NaN 值调用 histogram 会继续引发使用 nan 值时典型的 RuntimeWarning s,可以使用 errstate 像往常一样使其静音.

当给出显式 bin 边缘时, histogram 适用于 datetime 类型#

现在可以对日期,时间和时间差进行直方图处理.必须显式传递 bin 边缘,并且尚未自动计算.

histogram “auto” 估计器可以更好地处理有限的方差#

IQR 为 0 不再导致 n_bins=1 ,而是此时选择的 bin 数量与数据大小相关.

histogram ` 和 `` histogramdd `` 返回的边缘现在与数据浮点类型匹配#

当传递 `` np.float16 , np.float32 `` 或 `` np.longdouble `` 数据时,返回的边缘现在具有相同的 dtype. 以前,只有在给出显式 bins 时,`` histogram `` 才会返回相同的类型,并且无论输入是什么,`` histogram `` 都会生成`` float64 `` bins .

`` histogramdd `` 允许在轴的子集中给出显式范围#

`` numpy.histogramdd` 的 range 参数现在可以包含 None 值,以指示应从数据中计算相应轴的范围. 以前,无法在每个轴的基础上指定此范围.

histogramddhistogram2d 的 normed 参数已重命名#

这些参数现在称为 density ,这与 histogram 是一致的.旧参数继续有效,但应首选新名称.

np.r_ 可以处理 0 维数组,而 np.ma.mr_ 可以处理 np.ma.masked#

传递给 r_mr_ 连接辅助函数的 0 维数组现在被视为长度为 1 的数组. 以前,传递这些会报错. 因此, numpy.ma.mr_ 现在可以在 masked 常量上正常工作.

np.ptp 接受 keepdims 参数,并扩展了轴元组#

np.ptp (峰峰值)现在可以像 np.maxnp.min 一样在多个轴上工作.

MaskedArray.astype 现在与 ndarray.astype 相同#

这意味着它接受所有相同的参数,从而使为 ndarray 编写的更多代码也可以用于 masked array.

在编译时启用 AVX2/AVX512#

更改为 simd.inc.src 以允许在编译时使用 AVX2 或 AVX512. 以前,使用 -march=native 编译 avx2(或 512)仍然会对 simd 函数使用 SSE 代码,即使代码的其余部分获得了 AVX2.

nan_to_num 在接收标量或 0 维输入时始终返回标量#

以前,对于整数标量输入会返回一个数组,这与浮点输入的行为以及通常的 ufuncs 的行为不一致. 对于所有类型的标量或 0 维输入,现在的结果都是标量.

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 参数现在可以用于 0 维数组.

允许 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 中的快速路径. 以前,快速路径仅用于一维数组.

广义 ufuncs 现在接受 axes , axiskeepdims 参数#

可以通过传入 axes 参数(特定轴的索引的元组列表)来控制广义 ufunc 在哪些轴上运行. 例如,对于适用于矩阵乘法的 (i,j),(j,k)->(i,k) 签名,基本元素是二维矩阵,并且这些矩阵被认为存储在每个参数的最后两个轴中. 对应的 axes 关键字将是 [(-2, -1), (-2, -1), (-2, -1)] . 如果想要使用前导维度,则可以传入 [(0, 1), (0, 1), (0, 1)] .

为了简化,对于作用于 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_axisnp.put_along_axis 函数#

当用于多维数组时, argsort , argmin , argmaxargpartition 返回的数组难以用作索引. take_along_axis 提供了一种使用这些索引在数组中查找值的简便方法,因此:

np.take_along_axis(a, np.argsort(a, axis=axis), axis=axis)

与以下内容相同:

np.sort(a, axis=axis)

np.put_along_axis 充当在数组中写入这些索引的双重操作.