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.stacknumpy.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,一个函数,用于获取直方图使用的箱的边缘,而无需计算直方图。

  • 已添加 C 函数 npy_get_floatstatus_barriernpy_clear_floatstatus_barrier 来处理编译器优化更改操作顺序的情况。有关详细信息,请参见下文。

弃用#

  • 内置 pickle 函数的别名已弃用,推荐使用未加别名的 pickle.<func> 名称

    • numpy.loads

    • numpy.core.numeric.load

    • numpy.core.numeric.loads

    • numpy.ma.loadsnumpy.ma.dumps

    • numpy.ma.loadnumpy.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() 现在返回视图而不是列表。这与 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始终返回列表#

这是文档化的行为,但以前结果可能是切片、None或列表中的任何一个。

所有下游用户似乎都在检查flatnotmasked_contiguous返回的None结果,并将其替换为[]。这些调用者将继续像以前一样工作。

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

1.7.0版本之前,numpy.squeeze没有axis参数,并且默认情况下所有空轴都被移除。加入axis参数使得可以选择性地压缩单个或多个空轴成为可能,但是旧的API期望没有得到遵守,因为仍然可以从期望删除所有空轴的对象中选择性地移除轴(静默成功)。针对期望旧行为的对象,这种静默选择性地移除空轴的问题已得到修复,并恢复了旧的行为。

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

.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函数。当在ufunc SIMD函数中使用以前的函数时,像GCC 8.1和Clang这样的优化编译器会重新排列操作顺序,导致在运行我们想要检查其状态的操作之前检查floatstatus标志。参见#10339

PyArray_GetDTypeTransferFunction的更改#

PyArray_GetDTypeTransferFunction现在默认情况下使用用户定义的copyswapn/copyswap来处理用户定义的dtype。如果这会导致严重的性能下降,请考虑实现copyswapn以反映PyArray_GetStridedCopyFn的实现。参见#10898

新功能#

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

这些分别计算最大公约数和最小公倍数。它们适用于所有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。

  • greedy路径已更新为包含更多动态规划思想,避免了大量重复(且代价高昂)的调用,这些调用计算实际发生的配对收缩。现在在数百个输入张量上只需几秒钟即可完成。对于矩阵产品状态理论很有用。

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

  • 增强了can_dot功能,该功能以前错过了一个边缘情况(gh-11308的一部分)。

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

np.flip现在在其axis参数中接受None或整数元组。如果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 *

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

之前,在尝试计算数据的有限范围时会失败。由于当显式给出 bin 时范围会被忽略,因此此错误是多余的。

请注意,对 NaN 值调用 histogram 将继续引发处理 nan 值时常见的 RuntimeWarning,这可以使用 errstate 像往常一样消除。

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

现在可以对日期、时间和时间差进行直方图统计。必须显式传递 bin 边界,目前尚不能自动计算。

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

IQR 为 0 不会再导致 n_bins=1,在这种情况下,选择的 bin 数量与数据大小相关。

histogramhistogramdd 返回的边界现在与数据浮点类型匹配#

当传递 np.float16np.float32np.longdouble 数据时,返回的边界现在具有相同的 dtype。之前,只有在给出显式 bin 时,histogram 才会返回相同的类型,而无论输入是什么,histogram 都会产生 float64 bin。

histogramdd 允许在部分轴上给出显式范围#

numpy.histogramddrange 参数现在可以包含 None 值,表示应根据数据计算相应轴的范围。以前,这无法按轴进行指定。

histogramddhistogram2dnormed 参数已重命名#

这些参数现在称为 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 在接收标量或 0d 输入时始终返回标量#

以前,对于整数标量输入会返回一个数组,这与浮点输入的行为以及 ufunc 的一般行为不一致。对于所有类型的标量或 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)

由于此更改,现在可以在 0d 数组上使用 period 参数。

允许在 Python 2 中使用 Unicode 作为 dtype 字段名#

以前,在 Python 2 中,np.dtype([(u'name', float)]) 会引发 TypeError,因为字段名只允许使用字节字符串。现在,任何 Unicode 字符串字段名都将使用 ascii 编码器进行编码,并在失败时引发 UnicodeEncodeError

此更改使使用 from __future__ import unicode_literals 编写 Python 2/3 兼容代码更容易,这在以前会导致字符串字面量字段名在 Python 2 中引发 TypeError。

比较 ufunc 接受 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',从而明确其意图。

对于就地累加,不要创建临时副本#

当 ufunc 执行累加时,由于输入和输出之间的重叠,它们不再创建临时副本,也就是说,在累加结果存储到位之前,会添加下一个累加的元素,因此重叠是安全的。避免复制可以加快执行速度。

linalg.matrix_power 现在可以处理矩阵堆栈#

linalg中的其他函数一样,matrix_power现在可以处理维度大于2的数组,这些数组被视为矩阵堆栈。作为更改的一部分,为了进一步提高一致性,第一个参数的名称已更改为a(从M),非方阵的异常已更改为LinAlgError(从ValueError)。

提高了random.permutation中多维数组的性能#

permutation对所有输入数组维度都使用random.shuffle中的快速路径。以前,快速路径仅用于一维数组。

广义ufunc现在接受axesaxiskeepdims参数#

可以通过传递axes参数(包含特定轴索引的元组列表)来控制广义ufunc作用的轴。例如,对于矩阵乘法合适的签名(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_axisnp.put_along_axis函数#

当用于多维数组时,argsortargminargmaxargpartition返回难以用作索引的数组。take_along_axis提供了一种简单的方法来使用这些索引查找数组中的值,因此

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

np.sort(a, axis=axis)

np.put_along_axis作为写入数组中这些索引的双重操作。