NumPy 1.16.0 发行说明#

此 NumPy 版本是最后一个支持 Python 2.7 的版本,并将作为长期版本维护,直到 2020 年进行错误修复.已删除对 Python 3.4 的支持,支持的 Python 版本为 2.7 和 3.5-3.7.PyPI 上的 wheels 与 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/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.histogram normed 参数已弃用.它以前已被弃用,但未发出警告.

  • 应用于非数字数组的 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 运行.作为模块 python -m numpy.f2py [...] 运行 f2py 将在任何 NumPy 版本中无需修改路径即可工作.

NaT 比较#

与 NaN 的行为一致,所有与 datetime64 或 timedelta64 NaT("not-a-time")值进行的不等式检查之外的比较现在总是返回 False ,而与 NaT 进行的不等式检查现在总是返回 True .这包括 NaT 值之间的比较.为了与旧行为兼容,请使用 np.isnat 显式检查 NaT,或在使用 datetime64/timedelta64 数组进行比较之前使用 .astype(np.int64) 转换它们.

complex64/128 对齐已更改#

现在,复数类型的内存对齐方式与由两个浮点值组成的 C 结构相同,而以前,复数类型的内存对齐方式等于该类型的大小.对于许多用户(例如 x64/unix/gcc),这意味着 complex64 现在是 4 字节对齐而不是 8 字节对齐.一个重要的后果是,对齐的结构化 dtype 现在可能具有不同的大小.例如, 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 关键字参数来指定用于 unraveling 的数组的形状. 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') 替换.请参阅 user guide 的"访问多个字段"部分.

C API 变更#

由于添加了以下内容, NPY_FEATURE_VERSION 已递增至 0x0000D:

新特性#

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

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

np.loadtxt 添加了 max_rows 关键字#

numpy.loadtxt 中的新关键字 max_rows 设置在 numpy.genfromtxt 中那样,在 skiprows 之后要读取的最大行数.

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

现在,对于 np.timedelta64 类型的两个操作数支持模(余数)运算符.操作数可能具有不同的单位,并且返回值将匹配操作数的类型.

改进#

numpy 数组的无复制 pickle#

直到协议 4,numpy 数组 pickle 都会创建 2 个被序列化数据的虚假副本. 使用 pickle 协议 5 和 PickleBuffer API,现在可以使用带外缓冲区无复制地序列化各种 numpy 数组,并使用带内缓冲区少复制一次. 对于大型数组,这将导致峰值内存使用量最多减少 66%.

构建 shell 独立性#

NumPy 构建不应再直接与主机 shell 交互.在适当的情况下, exec_command 已替换为 subprocess.check_output .

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

当在支持它的前端中使用时, Polynomial 实例现在通过 LaTeX 渲染.当前的格式是实验性的,可能会发生变化.

randintchoice 现在可以在空分布上工作#

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

linalg.lstsq , linalg.qr , 和 linalg.svd 现在可以处理空数组#

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

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

这应该有助于追踪问题.

Einsum 优化路径更新和效率提升#

Einsum 已与当前的上游工作同步.

numpy.anglenumpy.expand_dims 现在可以在 ndarray 子类上工作#

特别是,它们现在可以用于 masked arrays.

NPY_NO_DEPRECATED_API 编译器警告抑制#

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

np.diff 添加了 kwargs prepend 和 append#

新的 kwargs prependappend ,允许在差异的任一端插入值.类似于 ediff1d 的选项.现在可以通过 prepend=0 轻松获得 cumsum 的逆.

ARM 支持已更新#

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

附加到构建标志#

numpy.distutils 总是覆盖而不是附加到 LDFLAGS 和其他类似的用于编译 Fortran 扩展的环境变量.现在,如果将 NPY_DISTUTILS_APPEND_FLAGS 环境变量设置为 1,则行为将是附加.这适用于:LDFLAGS , F77FLAGS , F90FLAGS , FREEFLAGS , FOPT , FDEBUGFFLAGS .有关更多详细信息,请参见 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.polyfit 中选项 cov 的新值 unscaled#

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

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

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

__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 来进行浮点状态错误报告. 以前我们有一个损坏的默认值,有时不会报告下溢,溢出和无效的浮点运算. 现在我们可以支持像 Alpine Linux 这样的非 glibc 发行版,只要它们附带 fenv.h .

加速大型数组的 np.block#

大型数组(大于 512 * 512 )现在使用一种基于将数据直接复制到结果数组的适当切片中的分块算法. 这为这些大型数组带来了显着的加速,特别是对于沿超过 2 个维度进行分块的数组.

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

以前,调用者负责在指针的整个生命周期内保持数组的活动状态.

加速只读数组的 np.take#

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

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

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

ufunc 身份在归约过程中表现更好#

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

在此版本中,逻辑二元 ufunc logical_and , logical_orlogical_xor 现在具有 bool 类型的 identity ,而以前它们是 int 类型. 这恢复了在用这些 ufunc 归约空对象数组时获得 bool 的 1.14 行为,同时保持了在用算术 ufunc(如 addmultiply )归约空对象数组时获得 int 的 1.15 行为.

此外,现在 logaddexp 具有 -inf 的单位元,允许在空序列上调用它,而之前这是不可能的.

这要归功于新的 PyUFunc_FromFuncAndDataAndSignatureAndIdentity ,它现在允许使用任意值作为单位元.

改进了从 ctypes 对象转换#

Numpy一直支持从 ctypes 中获取值或类型并将其转换为数组或 dtype,但仅对于更简单的类型表现正确. 从此版本开始,此警告已取消 - 现在:

  • ctypes.Structure_pack_ 属性用于模拟 C 的 __attribute__((packed)) ,现在可以正确处理.

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

  • 支持 ctypes.Union

  • 不可表示的构造会引发异常,而不是产生危险的不正确结果:

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

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

一个新的 ndpointer.contents 成员#

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

matmul 现在是一个 ufunc#

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

用于 linspace , logspacegeomspace 的起始和停止数组#

这些函数过去仅限于标量停止和起始值,但现在可以采用数组,这些数组将被正确广播并产生一个预先添加了一个轴的输出. 例如,这可以用于获得点集之间的线性插值点.

CI 扩展了其他服务#

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

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

  • 通过 shippable.com 进行 Arm 测试

  • Azure pipelines 上的其他测试运行

除了我们继续使用 travis,appveyor(用于 wheels)和 LGTM 之外,这些都是额外的.

变更#

比较 ufuncs 现在将出错,而不是返回 NotImplemented#

以前,比较 ufuncs(例如 np.equal )如果它们的参数具有结构化的 dtype,则会返回 NotImplemented ,以帮助比较运算符(例如 __eq__ )处理这些 dtype. 这不再需要了,因为相关的逻辑已移至比较运算符 proper (因此会根据需要继续返回 NotImplemented ). 因此,像所有其他 ufuncs 一样,比较 ufuncs 现在将对结构化的 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) ,而是使用 chisq/(M-N-2) 进行缩放,其中 M 是数据点的数量,N 是参数的数量. 这种缩放与诸如 scipy.optimize.curve_fit 之类的其他拟合程序不一致,并已更改为 chisq/(M-N) .

maximumminimum 不再发出警告#

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

Umath 和 multiarray c-extension 模块合并为一个模块#

这两个模块根据 NEP 15 合并了.之前 np.core.umathnp.core.multiarray 是独立的 c-extension 模块.现在它们是单个 np.core/_multiarray_math c-extension 模块的 Python 包装器.

扩展了 getfield 有效性检查#

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

NumPy 函数现在支持使用 __array_function__ 进行覆盖#

NumPy 有一个新的实验性机制,通过定义一个 __array_function__ 方法来覆盖非 NumPy 数组上几乎所有 NumPy 函数的实现,如 NEP 18 中所述.

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

基于只读缓冲区的数组不能设置为 writeable#

我们现在禁止在从 fromstring(readonly-buffer) 创建的数组上设置 writeable 标志为 True.