NumPy 1.15.0 发布说明#

NumPy 1.15.0 是一个包含大量清理工作、许多旧函数弃用以及许多现有函数改进的版本.请阅读下面的详细描述,看看您是否受到影响.

为了测试,我们已切换到 pytest 作为不再维护的 nose 框架的替代品.旧的基于 nose 的接口仍然保留给可能仍在使用它的下游项目.

此版本支持的 Python 版本是 2.7, 3.4-3.7.轮子与 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 函数,是 percentile 的一个接口,不需要乘以100的因子

  • numpy.nanquantile 函数,是 nanpercentile 的接口,不需要乘以100的因子

  • numpy.printoptions 是一个上下文管理器,它暂时为 with 块的范围设置打印选项:

    >>> with np.printoptions(precision=2):
    ...     print(np.array([2.0]) / 3)
    [0.67]
    
  • numpy.histogram_bin_edges 是一个函数,用于在不计算直方图的情况下获取直方图中各箱的边缘.

  • 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.

  • np.histogramnormed 参数,在 1.6.0 版本中早已弃用,现在会发出 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() 现在返回视图而不是列表.这与内置 dict 类型在 Python 2 和 Python 3 之间的变化一致.

在某些条件下,``nditer`` 必须在上下文管理器中使用#

当使用带有 "writeonly""readwrite" 标志的 numpy.nditer 时,在某些情况下,nditer 实际上不会给你一个可写数组的视图.相反,它会给你一个副本,如果你对副本进行了更改,nditer 稍后会将这些更改写回到实际数组中.目前,这种写回操作发生在数组对象被垃圾回收时,这使得在 CPython 上这个 API 容易出错,而在 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 为 ctypes 中的所有整数类型添加了 __array_interface__ 属性.

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

这是记录的行为,但以前的结果可能是切片、None 或列表.

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

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

1.7.0 版本之前,`numpy.squeeze` 没有 axis 参数,默认情况下会移除所有空轴.引入 axis 参数使得可以选择性地挤压单个或多个空轴,但由于仍然可以选择性地移除轴(静默成功),这不符合旧 API 的预期,因为对象期望移除所有空轴.对于期望旧行为的对象,静默选择性移除空轴的问题已得到修复,并恢复了旧行为.

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

.item 现在返回一个 bytes 对象,而不是缓冲区或字节数组.这可能会影响假设返回值是可变的代码,因为现在不再是这种情况.

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

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

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

对结构化数组的多字段索引返回视图而不是副本的更改推迟到1.16.引入了一个新方法 numpy.lib.recfunctions.repack_fields 来帮助缓解这一更改的影响,该方法可用于编写兼容numpy 1.15和1.16的代码.有关如何更新代码以适应未来更改的更多信息,请参阅 用户指南 的”访问多个字段”部分.

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 现在默认使用用户定义的 copyswapn / copyswap 用于用户定义的 dtypes.如果这导致显著的性能下降,考虑实现 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 个编译构建产物组合成一个单一的”胖”二进制文件.

return_indices 关键字已添加到 np.intersect1d#

新关键字 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 现在接受 None 或整数的元组作为其 axis 参数.如果 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 *.

histogram 在明确给出箱子时将接受NaN值#

之前在尝试为数据计算有限范围时会失败.由于在明确给出箱子时无论如何都会忽略范围,这个错误是多余的.

请注意,对 NaN 值调用 histogram 会继续引发处理 nan 值时典型的 RuntimeWarning ,这可以像往常一样通过 errstate 静默.

histogram 在给定显式 bin 边缘时,适用于日期时间类型.#

日期、时间和时间增量现在可以进行直方图处理.必须显式传递 bin 边缘,目前还不能自动计算.

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

不再有 IQR 为 0 时导致 n_bins=1 的情况,而是在这种情况下选择的箱数与数据大小相关.

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

当传递 np.float16np.float32np.longdouble 数据时,返回的边缘现在具有相同的 dtype.以前,只有明确给出箱子时,``histogram`` 才会返回相同类型,无论输入是什么,``histogram`` 都会生成 float64 箱子.

histogramdd 允许在部分轴上显式指定范围#

numpy.histogramddrange 参数现在可以包含 None 值,以表示相应轴的范围应从数据中计算.以前,这不能在每个轴的基础上指定.

histogramddhistogram2d 的归一化参数已被重命名#

这些参数现在被称为 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.maxnp.min 一样在多个轴上工作.

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

这意味着它接受所有相同的参数,使得为 ndarray 编写的更多代码也能用于掩码数组.

在编译时启用 AVX2/AVX512#

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

nan_to_num 在接收到标量或0维输入时总是返回标量#

以前,整数标量输入返回的是一个数组,这与浮点输入的行为不一致,也与一般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 数组上使用.

在 Python 2 中允许 dtype 字段名称为 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 中提高了多维数组的性能#

permutationrandom.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)].

为了简化,对于操作一维数组(向量)的通用ufuncs,可以接受单个整数而不是单元素元组,并且对于所有输出都是标量的通用ufuncs,可以省略(空)输出元组.因此,对于适用于内积的``(i),(i)->()``签名,可以传入``axes=[0, 0]``来指示向量存储在两个输入参数的第一个维度中.

对于类似于归约的广义ufuncs的快捷方式,即对单个共享核心维度起作用的归约,例如上面的内积示例,可以传递一个 axis 参数.这等同于使用该核心维度为所有参数传递 axes ,且条目相同(例如,对于上面的示例,``axes=[(axis,), (axis,)]``).

此外,就像对于归约一样,对于所有输入的核心维度数量相同且输出没有核心维度的广义ufuncs,可以传入 keepdims 以在输出中保留一个大小为1的维度,从而允许与原始输入进行适当的广播.额外维度的位置可以通过 axes 控制.例如,对于内积示例,``keepdims=True, axes=[-2, -2, -2]`` 将作用于内积示例,``keepdims=True, axis=-2`` 将作用于输入参数的倒数第二维度,并在输出中在该位置留下一个大小为1的维度.

在ppc系统上,float128值现在可以正确打印#

之前在ppc上打印float128值时存在错误,因为这些系统上的特殊双双浮点格式未被考虑.现在float128以正确的舍入和唯一性打印.

警告 ppc 用户:如果 glibc 版本 <=2.23,尤其是使用 float128 时,应升级 glibc.在 ppc 上,这些版本的 glibc 的 malloc 经常错误对齐分配的内存,这在使用 float128 值时可能会导致 numpy 崩溃.

新的 np.take_along_axisnp.put_along_axis 函数#

当用于多维数组时,``argsort``、argminargmaxargpartition 返回的数组作为索引使用起来很困难.``take_along_axis`` 提供了一种简单的方法来使用这些索引在数组中查找值,因此:

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

与以下内容相同:

np.sort(a, axis=axis)

np.put_along_axis 作为在数组内这些索引处写入的双重操作.