NumPy 1.16.0 版本说明#

此 NumPy 版本是最后一个支持 Python 2.7 的版本,并将作为长期支持版本维护,直到 2020 年进行错误修复。对 Python 3.4 的支持已取消,支持的 Python 版本为 2.7 和 3.5-3.7。PyPI 上的轮子与 OpenBLAS v0.3.4+ 链接,这应该可以修复先前 OpenBLAS 版本中发现的已知线程问题。

构建此版本的后续开发者应使用 Cython >= 0.29,如果使用 OpenBLAS,则应使用 OpenBLAS > v0.3.4。

此版本进行了大量的重构,并包含许多错误修复、改进的代码组织和更好的跨平台兼容性。并非所有这些改进都对用户可见,但它们应该有助于简化未来的维护工作。

亮点#

  • 对覆盖 numpy 函数的实验性(仅限选择加入)支持,请参见下面的 __array_function__

  • matmul 函数现在是一个 ufunc。这提供了更好的性能,并允许使用 __array_ufunc__ 进行覆盖。

  • 改进了对 ARM 和 POWER 架构的支持。

  • 改进了对 AIX 和 PyPy 的支持。

  • 改进了与 ctypes 的互操作性。

  • 改进了对 PEP 3118 的支持。

新函数#

  • numpy.lib.recfuntions 模块添加了新函数,以简化结构化赋值更改

    • assign_fields_by_name

    • structured_to_unstructured

    • unstructured_to_structured

    • apply_along_fields

    • require_fields

    有关更多信息,请参阅位于 <https://docs.scipy.org.cn/doc/numpy/user/basics.rec.html> 的用户指南。

新增弃用#

  • 类型字典 numpy.core.typeNAnumpy.core.sctypeNA 已弃用。它们存在错误且未记录,将在 1.18 版本中移除。请改用 numpy.sctypeDict

  • numpy.asscalar 函数已弃用。它是功能更强大的 numpy.ndarray.item 的别名,未经测试,并且对于标量会失败。

  • numpy.set_array_opsnumpy.get_array_ops 函数已弃用。作为 NEP 15 的一部分,它们已与 C-API 函数 PyArray_SetNumericOpsPyArray_GetNumericOps 一起弃用。希望覆盖内置 ufunc 中内部循环函数的用户应使用 PyUFunc_ReplaceLoopBySignature

  • numpy.unravel_index 的关键字参数 dims 已弃用,请改用 shape

  • numpy.histogramnormed 参数已弃用。它之前已弃用,但未发出警告。

  • 应用于非数值数组的 positive 运算符(+)已弃用。请参见下文了解详情。

  • 将迭代器传递给堆栈函数已弃用

已过期弃用#

  • NaT 比较现在返回 False 且不发出警告,完成从 NumPy 1.11 开始的弃用周期。

  • np.lib.function_base.unique 已移除,完成从 NumPy 1.4 开始的弃用周期。请改用 numpy.unique

  • 多字段索引现在返回视图而不是副本,完成从 NumPy 1.7 开始的弃用周期。此更改先前在 NumPy 1.14 中尝试过,但已恢复到当前状态。

  • np.PackageLoadernp.pkgload 已移除。这些在 1.10 中已弃用,没有测试,并且似乎在 1.15 中不再有效。

未来的更改#

  • NumPy 1.17 将取消对 Python 2.7 的支持。

兼容性说明#

Windows 上的 f2py 脚本#

在 Windows 上,用于运行 f2py 的已安装脚本现在是 .exe 文件而不是 *.py 文件,并且只要 Scripts 目录位于路径中,就应从命令行将其作为 f2py 运行。在任何版本的 NumPy 中,将 f2py 作为模块运行 python -m numpy.f2py [...] 将无需修改路径即可工作。

NaT 比较#

与 NaN 的行为一致,除不等式检查外,所有与 datetime64 或 timedelta64 NaT(“非时间”)值的比较现在始终返回 False,而与 NaT 的不等式检查现在始终返回 True。这包括 NaT 值之间的比较。为了与旧行为兼容,请使用 np.isnat 显式检查 NaT,或者在进行比较之前使用 .astype(np.int64) 转换 datetime64/timedelta64 数组。

complex64/128 对齐已更改#

复数类型的内存对齐现在与由两个浮点值组成的 C 结构相同,而之前则等于类型的 size。对于许多用户(例如在 x64/unix/gcc 上),这意味着 complex64 现在是 4 字节对齐而不是 8 字节对齐。一个重要的结果是,对齐的结构化 dtype 现在可能具有不同的 size。例如,np.dtype('c8,u1', align=True) 过去在 (x64/gcc) 上的 itemsize 为 16,但现在为 12。

更详细地说,complex64 类型的对齐现在与 C 结构 struct {float r, i;} 相同,根据用于编译 numpy 的编译器,complex128 和 complex256 类型也是如此。

nd_grid __len__ 移除#

len(np.mgrid)len(np.ogrid) 现在被认为没有意义,并引发 TypeError

np.unravel_index 现在接受 shape 关键字参数#

以前,只接受 dims 关键字参数来指定用于解开的数组的形状。dims 仍然受支持,但现在已弃用。

多字段视图返回视图而不是副本#

使用多个字段对结构化数组进行索引,例如 arr[['f1', 'f3']],返回原始数组中的视图而不是副本。返回的视图通常会具有对应于原始数组中中间字段的额外填充字节,这与之前不同,这会影响诸如 arr[['f1', 'f3']].view('float64') 之类的代码。此更改已自 numpy 1.7 以来一直计划。自那时以来,遇到此路径的操作已发出 FutureWarnings。在 1.12 中添加了关于此更改的其他 FutureWarnings

为了帮助用户更新其代码以解决这些更改,已向 numpy.lib.recfunctions 模块添加了许多函数,这些函数可以安全地执行此类操作。例如,上面的代码可以用 structured_to_unstructured(arr[['f1', 'f3']], dtype='float64') 替换。请参阅 用户指南 中的“访问多个字段”部分。

C API 更改#

NPY_FEATURE_VERSION 已增加到 0x0000D,因为添加了

新功能#

将集成平方误差 (ISE) 估计器添加到 histogram#

此方法(bins='stone')用于优化 bin 数量,它是 Scott 规则的推广。Scott 规则假设分布近似为正态分布,而 ISE 是一种基于交叉验证的非参数方法。

np.loadtxt 添加了 max_rows 关键字#

numpy.loadtxt 中新增了关键字 max_rows,用于设置在 skiprows 之后读取内容的最大行数,类似于 numpy.genfromtxt

np.timedelta64 操作数添加了模运算符支持#

现在支持对两个 np.timedelta64 类型操作数进行模运算(求余数)。操作数可以具有不同的单位,返回值将与操作数的类型匹配。

改进#

NumPy 数组的无复制序列化#

在协议 4 之前,NumPy 数组的序列化会创建两份冗余的数据副本。使用 pickle 协议 5 和 PickleBuffer API,现在可以无需任何复制地使用带外缓冲区序列化各种 NumPy 数组,并使用带内缓冲区减少一份复制。对于大型数组,这会导致峰值内存使用量最多下降 66%。

构建的shell独立性#

NumPy 构建不再直接与主机 shell 交互。已将 exec_command 替换为适当的 subprocess.check_output

np.polynomial.Polynomial 类在 Jupyter Notebook 中以 LaTeX 渲染#

在支持它的前端中使用时,Polynomial 实例现在通过 LaTeX 渲染。当前格式为实验性格式,可能会更改。

randintchoice 现在可以处理空分布#

即使不需要绘制任何元素,当参数描述空分布时,np.random.randintnp.random.choice 也会引发错误。此问题已修复,例如 np.random.choice([], 0) == np.array([], dtype=float64)

linalg.lstsqlinalg.qrlinalg.svd 现在可以处理空数组#

以前,当传入空矩阵/空矩阵(具有零行和/或零列)时,会引发 LinAlgError。现在将返回适当形状的输出。

链接异常以针对无效的 PEP3118 格式字符串提供更好的错误消息#

这应该有助于查找问题。

Einsum 优化路径更新和效率改进#

Einsum 已与当前上游工作同步。

numpy.anglenumpy.expand_dims 现在可在 ndarray 子类上运行#

特别是,它们现在适用于掩码数组。

NPY_NO_DEPRECATED_API 编译器警告抑制#

NPY_NO_DEPRECATED_API 设置为 0 将在使用已弃用的 NumPy API 时抑制当前的编译器警告。

np.diff 添加了关键字参数 prepend 和 append#

新的关键字参数 prependappend 允许在差值的任一端插入值。类似于 ediff1d 的选项。现在可以通过 prepend=0轻松获得 cumsum 的逆。

ARM 支持更新#

ARM CPU 的支持已更新,以适应 32 位和 64 位目标,以及大端和小端字节序。已解决 AARCH32 内存对齐问题。CI 测试已扩展到通过 shippable.com 的服务包含 AARCH64 目标。

附加到构建标志#

numpy.distutils 一直覆盖而不是附加到 LDFLAGS 和其他类似的环境变量以编译 Fortran 扩展。现在,如果 NPY_DISTUTILS_APPEND_FLAGS 环境变量设置为 1,则行为将为附加。这适用于:LDFLAGSF77FLAGSF90FLAGSFREEFLAGSFOPTFDEBUGFFLAGS。有关更多详细信息,请参阅 gh-11525。

通用 ufunc 签名现在允许固定大小的维度#

通过在通用 ufunc 的签名中使用数值,可以指示给定函数需要具有给定大小的维度的输入或输出。例如,将极角转换为二维笛卡尔单位向量的函数的签名将为 ()->(2);将两个球面角转换为三维单位向量的函数的签名将为 (),()->(3);两个三维向量的叉积的签名将为 (3),(3)->(3)

请注意,对于基本函数,这些维度与用字母开头的名称指示的可变维度没有任何不同;循环仍然传递相应的大小,但现在可以依赖该大小等于签名中给定的固定大小。

通用 ufunc 签名现在允许灵活的维度#

某些函数,特别是 NumPy 对 @ 的实现作为 matmul,与通用 ufunc 非常相似,因为它们在核心维度上进行运算,但是由于它们能够处理缺少维度的输入,因此不能将它们表示为通用 ufunc。为了支持这一点,现在允许在维度名称后添加问号以指示该维度不一定必须存在。

通过此添加,matmul 的签名可以表示为 (m?,n),(n,p?)->(m?,p?)。这表示如果例如第二个操作数只有一个维度,则对于基本函数,它将被视为该输入具有核心形状 (n, 1),并且输出具有相应的核心形状 (m, 1)。但是,实际的输出数组已删除灵活的维度,即它将具有形状 ..., m)。同样,如果两个参数只有一个维度,则将输入表示为具有形状 (1, n)(n, 1) 提供给基本函数,输出为 (1, 1),而返回的实际输出数组将具有形状 ()。通过这种方式,签名允许对四个相关的但不同的签名使用单个基本函数,(m,n),(n,p)->(m,p)(n),(n,p)->(p)(m,n),(n)->(m)(n),(n)->()

np.clipclip 方法检查内存重叠#

现在始终测试这些函数的 out 参数的内存重叠,以避免发生内存重叠时出现损坏的结果。

np.polyfitcov 选项的新值 unscaled#

已向 np.polyfit 函数的 cov 参数添加了另一个可能的值。使用 cov='unscaled' 将完全禁用协方差矩阵的缩放(类似于在 scipy.optimize.curve_fit 中设置 absolute_sigma=True)。这在某些情况下很有用,例如权重由 1/sigma 给出,其中 sigma 是(已知的)(高斯分布)数据点的标准误差,在这种情况下,未缩放的矩阵已经是协方差矩阵的正确估计。

标量数值类型的详细文档字符串#

当应用于数值类型(例如 numpy.intcnumpy.int_numpy.longlong)时,help 函数现在会列出该类型的所有别名,并区分平台相关和平台无关的别名。

__module__ 属性现在指向公共模块#

大多数 NumPy 函数的 __module__ 属性已更新,指向访问函数的首选公共模块,而不是函数实际定义所在的模块。这使得在 IPython 等工具中显示函数信息更加清晰,例如,您现在看到的是 <function 'numpy.sum'>,而不是 <function 'numpy.core.fromnumeric.sum'>

标记为适合透明巨页的大型分配#

在支持通过 madvise 系统调用进行透明巨页的系统上,NumPy 现在会标记大型内存分配可以使用巨页作为支持,这减少了页面错误开销,在某些严重依赖页面错误的场景中可以显著提高性能。在 Linux 系统上,必须将使用巨页的设置 /sys/kernel/mm/transparent_hugepage/enabled 设置为至少 madvise。如果系统已将其设置为 always,则不会看到太大区别,因为内核会在适当的情况下自动使用巨页。

使用非常旧的 Linux 内核(约 3.x 及更旧版本)的用户应确保 /sys/kernel/mm/transparent_hugepage/defrag 未设置为 always,以避免由于内存碎片整理中的并发问题而导致的性能问题。

Alpine Linux(以及其他 musl c 库发行版)支持#

我们现在默认使用 fenv.h 来报告浮点状态错误。以前,我们的默认设置存在问题,有时无法报告下溢、上溢和无效的浮点运算。现在,只要它们提供了 fenv.h,我们就可以支持 Alpine Linux 等非 glibc 发行版。

加快大型数组的 np.block 速度#

大型数组(大于 512 * 512)现在使用基于将数据直接复制到结果数组的适当切片的阻塞算法。这使得这些大型数组的速度显著提高,特别是对于沿两个以上维度进行阻塞的数组。

arr.ctypes.data_as(...) 保持对 arr 的引用#

以前,调用者负责在指针的生命周期内保持数组的有效性。

加快只读数组的 np.take 速度#

np.takewriteable 标志设置为 False 时,np.take 的实现不再对源数组进行不必要的复制。

更多函数支持路径类对象#

np.core.records.fromfile 函数现在除了支持文件对象外,还支持 pathlib.Path 和其他路径类对象。此外,当使用内存映射(mmap_mode 关键字参数)时,np.load 函数现在也支持路径类对象。

改进约简期间 ufunc 恒等式的行为#

通用函数具有一个 .identity 属性,当在空轴上调用 .reduce 时使用。

在本版本中,逻辑二元 ufunc,logical_andlogical_orlogical_xor,现在具有 identity 类型为 bool,而以前它们是 int 类型。这恢复了 1.14 版本的行为,即在使用这些 ufunc 对空对象数组进行约简时获得 bool 值,同时保留了 1.15 版本的行为,即在使用 addmultiply 等算术 ufunc 对空对象数组进行约简时获得 int 值。

此外,logaddexp 现在具有 -inf 的恒等式,允许它在空序列上调用,而以前则不行。

这要感谢新的 PyUFunc_FromFuncAndDataAndSignatureAndIdentity,它现在允许使用任意值作为恒等式。

改进从 ctypes 对象的转换#

NumPy 一直支持从 ctypes 获取值或类型并将其转换为数组或 dtype,但只对更简单的类型表现正确。在本版本中,此限制已解除 - 现在

  • 尊重 ctypes.Structure_pack_ 属性,用于模拟 C 的 __attribute__((packed))

  • 保留所有 ctypes 对象的字节序

  • 支持 ctypes.Union

  • 不可表示的结构会引发异常,而不是产生危险的错误结果

    • 位域不再被解释为子数组

    • 指针不再被替换为它们指向的类型

新的 ndpointer.contents 成员#

这与普通 ctypes 数组的 .contents 成员匹配,可用于围绕指针内容构造 np.array。这取代了 np.array(some_nd_pointer),该方法在 1.15 版本中停止工作。由于此更改的副作用,ndpointer 现在支持具有重叠字段和填充的 dtype。

matmul 现在是 ufunc#

numpy.matmul 现在是一个 ufunc,这意味着 __matmul__ 函数和运算符现在都可以被 __array_ufunc__ 覆盖。它的实现也发生了变化。它使用与 numpy.dot 相同的 BLAS 例程,确保其在大矩阵上的性能相似。

linspacelogspacegeomspace 的起始和终止数组#

这些函数过去仅限于标量终止值和起始值,但现在可以接受数组,这些数组将被正确广播,并产生在前面附加一个轴的输出。例如,这可以用来获得点集之间的线性插值点。

CI 扩展了其他服务#

感谢提供服务的公司,我们现在使用了额外的免费 CI 服务

  • 通过 codecov.io 进行代码覆盖率测试

  • 通过 shippable.com 进行 Arm 测试

  • 在 azure pipelines 上进行额外测试运行

这些服务补充了我们持续使用的 travis、appveyor(用于 wheels)和 LGTM。

更改#

比较 ufunc 现在将引发错误,而不是返回 NotImplemented#

以前,如果比较 ufunc(例如 np.equal)的参数具有结构化 dtype,则会返回 NotImplemented,以帮助比较运算符(例如 __eq__)处理这些情况。这不再需要,因为相关的逻辑已移动到适当的比较运算符(因此它们确实会继续返回 NotImplemented,根据需要)。因此,与所有其他 ufunc 一样,比较 ufunc 现在将在结构化 dtype 上引发错误。

对于非数值数组,positive 现在将引发弃用警告#

以前,+array 无条件地返回一个副本。现在,如果数组不是数值型(即,如果 np.positive(array) 引发 TypeError),它将引发 DeprecationWarning。对于覆盖默认 __array_ufunc__ 实现的 ndarray 子类,TypeError 将被传递。

NDArrayOperatorsMixin 现在实现了矩阵乘法#

之前,np.lib.mixins.NDArrayOperatorsMixin没有实现Python矩阵乘法运算符(@)的特殊方法。现在matmul是一个ufunc,并且可以使用__array_ufunc__重写,这种情况已经改变。

np.polyfit中协方差矩阵的缩放比例有所不同#

到目前为止,np.polyfit在协方差矩阵的缩放比例中使用了非标准因子。也就是说,它使用chisq/(M-N-2)而不是标准的chisq/(M-N)进行缩放,其中M是数据点的数量,N是参数的数量。这种缩放比例与其他拟合程序(例如scipy.optimize.curve_fit)不一致,现已更改为chisq/(M-N)

maximumminimum不再发出警告#

作为1.10版中引入的代码的一部分,当使用SSE2语义时,在numpy.maximumnumpy.minimum中遇到NaN时,float32float64会设置无效浮点数状态。这导致有时会发出RuntimeWarning。在1.15版本中,我们修复了导致警告更加明显的 inconsistencies。现在不会发出任何警告。

Umath和multiarray C扩展模块合并为单个模块#

根据NEP 15,这两个模块已合并。以前np.core.umathnp.core.multiarray是独立的C扩展模块。现在它们是单个np.core/_multiarray_math C扩展模块的Python包装器。

getfield有效性检查已扩展#

numpy.ndarray.getfield现在检查dtype和offset参数,以防止访问无效的内存位置。

NumPy函数现在支持使用__array_function__进行重写#

NumPy 有一个新的实验机制,可以通过定义__array_function__方法来重写几乎所有 NumPy 函数在非 NumPy 数组上的实现,如 NEP 18 中所述。

此功能尚未默认启用,但已发布以方便潜在用户进行实验。有关设置相应环境变量的详细信息,请参阅 NEP。我们预计 NumPy 1.17 版本将默认启用重写,由于用 C 编写的新的实现,这也会更高效。

基于只读缓冲区的数组无法设置为writeable#

我们现在不允许将writeable标志设置为True,该标志用于通过fromstring(readonly-buffer)创建的数组。