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_namestructured_to_unstructuredunstructured_to_structuredapply_along_fieldsrequire_fields
更多信息请参见用户指南 <https://docs.scipy.org/doc/numpy/user/basics.rec.html>.
新的弃用#
类型字典 numpy.core.typeNA 和 numpy.core.sctypeNA 已被弃用.它们存在缺陷且未被记录,并将在 1.18 版本中移除.请改用
numpy.sctypeDict.numpy.asscalar 函数已被弃用.它是更强大的
numpy.ndarray.item的别名,未经过测试,并且在标量上失败.numpy.set_array_ops 和 numpy.get_array_ops 函数已被弃用.作为 NEP 15 的一部分,它们与 C-API 函数
PyArray_SetNumericOps和PyArray_GetNumericOps一起被弃用.希望覆盖内置 ufuncs 中内循环函数的用户应使用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.PackageLoader和np.pkgload已被移除.这些在1.10版本中已被弃用,没有测试,并且在1.15版本中似乎不再工作.
未来变化#
NumPy 1.17 将不再支持 Python 2.7.
兼容性说明#
Windows 上的 f2py 脚本#
在Windows上,用于运行f2py的安装脚本现在是一个 .exe 文件而不是 *.py 文件,并且应该在 Scripts 目录在路径中时从命令行运行 f2py.作为模块运行 python -m numpy.f2py [...] 在任何版本的NumPy中都无需路径修改即可工作.
NaT 比较#
与 NaN 的行为一致,所有与 datetime64 或 timedelta64 NaT(”非时间”)值的比较(不等于检查除外)现在总是返回 False,而不等于检查与 NaT 现在总是返回 True.这包括 NaT 值之间的比较.为了与旧行为兼容,请使用 np.isnat 显式检查 NaT 或在进行比较之前使用 .astype(np.int64) 转换 datetime64/timedelta64 数组.
complex64/128 对齐方式已更改#
复杂类型的内存对齐现在与由两个浮点值组成的C结构相同,而之前它等于该类型的大小.对于许多用户(例如在x64/unix/gcc上),这意味着complex64现在4字节对齐而不是8字节对齐.一个重要的后果是,对齐的结构化dtypes现在可能有不同的大小.例如,``np.dtype(‘c8,u1’, align=True)`` 以前在x64/gcc上的itemsize是16,但现在它是12.
更详细地说,根据用于编译numpy的编译器,complex64类型现在具有与C结构 struct {float r, i;} 相同的对齐方式,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.关于此更改的额外 FutureWarnings 在 1.12 中添加.
为了帮助用户更新他们的代码以适应这些变化,已经在 numpy.lib.recfunctions 模块中添加了许多函数,这些函数可以安全地进行此类操作.例如,上面的代码可以用 structured_to_unstructured(arr[['f1', 'f3']], dtype='float64') 替换.请参阅 用户指南 的”访问多个字段”部分.
C API 变化#
NPY_FEATURE_VERSION 由于以下内容的添加,增加到了 0x0000D:
新功能#
集成平方误差(ISE)估计器添加到 histogram#
这种方法 (bins='stone') 用于优化箱数是 Scott 规则的泛化.Scott 规则假设分布近似正态,而 ISE 是一种基于交叉验证的非参数方法.
为 np.loadtxt 添加了 max_rows 关键字#
新关键字 max_rows 在 numpy.loadtxt 中设置了在 skiprows 之后要读取的内容的最大行数,类似于 numpy.genfromtxt.
为 np.timedelta64 操作数添加了取模运算符支持#
模数(余数)运算符现在支持类型为 np.timedelta64 的两个操作数.操作数可以有不同的单位,返回值将与操作数的类型匹配.
改进#
numpy 数组的不可复制序列化#
在协议4之前,numpy数组的序列化创建了2个多余的数据副本.使用pickle协议5和``PickleBuffer`` API,现在可以使用带外缓冲区对各种numpy数组进行序列化而无需任何副本,使用带内缓冲区则少一个副本.对于大数组,这导致峰值内存使用量最多下降66%.
构建 shell 独立性#
NumPy 构建不应再直接与主机机器的 shell 交互.``exec_command`` 已在适当的地方被 subprocess.check_output 取代.
np.polynomial.Polynomial 类在 Jupyter 笔记本中以 LaTeX 呈现#
当在前端中使用时,`Polynomial` 实例现在通过 LaTeX 渲染.当前的格式是实验性的,并且可能会发生变化.
randint 和 choice 现在可以在空分布上工作#
即使不需要绘制元素,当参数描述了一个空分布时,``np.random.randint`` 和 np.random.choice 也会引发错误.这个问题已经修复,例如 np.random.choice([], 0) == np.array([], dtype=float64).
linalg.lstsq、linalg.qr 和 linalg.svd 现在可以处理空数组#
之前,当传递一个空矩阵/空矩阵(具有零行和/或零列)时,会引发 LinAlgError.现在返回适当形状的输出.
链式异常以提供更好的错误消息,用于无效的 PEP3118 格式字符串#
这应该有助于追踪问题.
Einsum 优化路径更新和效率改进#
Einsum 已与当前的上游工作同步.
numpy.angle 和 numpy.expand_dims 现在可以在 ndarray 子类上工作#
特别是,它们现在适用于掩码数组.
NPY_NO_DEPRECATED_API 编译器警告抑制#
将 NPY_NO_DEPRECATED_API 设置为 0 的值将抑制当前编译器在使用已弃用的 numpy API 时的警告.
np.diff 添加了 kwargs prepend 和 append#
新的 kwargs prepend 和 append,允许在差异的任一端插入值.类似于 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, FDEBUG, 和 FFLAGS.更多详情请参见 gh-11525.
广义ufunc签名现在允许固定大小的维度#
通过在广义ufunc的签名中使用数值,可以表明给定的函数要求输入或输出具有给定大小的维度.例如,将极角转换为二维笛卡尔单位向量的函数的签名将是 ()->(2);将两个球面角转换为三维单位向量的函数的签名将是 (),()->(3);而两个三维向量的叉积的签名将是 (3),(3)->(3).
请注意,对于基本函数,这些维度与以字母开头的名称指示的可变维度没有任何不同;循环仍然传递相应的尺寸,但它现在可以依赖于该尺寸等于签名中给出的固定尺寸.
广义ufunc签名现在允许灵活的维度#
一些函数,特别是 numpy 的 @ 作为 matmul 的实现,与广义 ufuncs 非常相似,因为它们在核心维度上操作,但由于它们能够处理缺少维度的输入,因此不能将它们表示为这样的函数.为了支持这一点,现在允许在维度名称后加上问号来表示该维度不一定必须存在.
通过这一添加,``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.clip 和 clip 方法检查内存重叠#
这些函数的 out 参数现在总是被测试以避免在发生内存重叠时导致结果损坏.
新值 unscaled 用于 np.polyfit 中的选项 cov#
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 进行浮点状态错误报告.之前我们有一个有问题的默认设置,有时不会报告下溢、上溢和无效的浮点操作.现在,只要它们提供 fenv.h,我们就可以支持像 Alpine Linux 这样的非 glibc 发行版.
加速 np.block 以处理大型数组#
对于大于 512 * 512 的大型数组,现在使用基于直接将数据复制到结果数组的适当切片中的分块算法.这显著提高了这些大型数组的处理速度,特别是对于沿着超过2个维度分块的数组.
arr.ctypes.data_as(...) 持有对 arr 的引用#
之前,调用者负责在指针的生命周期内保持数组的存活.
加速 np.take 对于只读数组#
当 np.take 的 writeable 标志设置为 False 时,``np.take`` 的实现不再对源数组进行不必要的复制.
支持更多函数的路径类对象#
np.core.records.fromfile 函数现在除了文件对象外,还支持 pathlib.Path 和其他类路径对象.此外,``np.load`` 函数在使用内存映射(mmap_mode 关键字参数)时也支持类路径对象.
在归约过程中ufunc标识的更好行为#
通用函数有一个 .identity ,当在空轴上调用 .reduce 时使用.
在此版本中,逻辑二元ufuncs,`logical_and`、logical_or 和 logical_xor,现在具有类型为 bool 的 identity,而之前它们是类型为 int.这恢复了在用这些ufuncs减少空对象数组时获得 bool 的1.14行为,同时在使用算术ufuncs(如 add 和 multiply)减少空对象数组时保持获得 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.这取代了 np.array(some_nd_pointer),它在 1.15 版本中停止工作.作为这个更改的副作用,``ndpointer`` 现在支持具有重叠字段和填充的 dtypes.
matmul 现在是一个 ufunc#
numpy.matmul 现在是一个 ufunc,这意味着函数和 __matmul__ 运算符现在都可以被 __array_ufunc__ 重写.它的实现也发生了变化.它使用与 numpy.dot 相同的 BLAS 例程,确保其性能对于大型矩阵是相似的.
linspace、logspace 和 geomspace 的起始和终止数组#
这些函数过去仅限于标量停止和开始值,但现在可以接受数组,这些数组将被正确广播,并在输出中预先添加一个轴.例如,这可以用于在点集之间获得线性插值点.
CI 扩展了额外的服务#
我们现在使用额外的免费 CI 服务,感谢提供这些服务的公司:
通过 codecov.io 进行代码覆盖率测试
通过 shippable.com 进行 Arm 测试
在 Azure Pipelines 上的额外测试运行
这些是我们继续使用 travis、appveyor(用于 wheels)和 LGTM 的补充.
更改#
比较 ufuncs 现在会报错而不是返回 NotImplemented#
之前,比较ufuncs例如 np.equal 如果它们的参数具有结构化dtypes,会返回 NotImplemented,以帮助比较运算符例如 __eq__ 处理这些情况.这不再需要,因为相关的逻辑已经移到比较运算符本身(因此它们继续根据需要返回 NotImplemented).因此,像所有其他ufuncs一样,比较ufuncs现在将在结构化dtypes上出错.
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).
maximum 和 minimum 不再发出警告#
作为 1.10 版本引入的一部分代码,当在 numpy.maximum 和 numpy.minimum 中遇到 Nan 时,使用 SSE2 语义时,``float32`` 和 float64 会设置无效的浮点状态.这有时会导致 RuntimeWarning 被发出.在 1.15 版本中,我们修复了导致这些警告变得更加显眼的不一致性.现在不会再发出警告.
Umath 和 multiarray c-扩展模块合并为一个模块#
根据 NEP 15 ,这两个模块被合并了.以前 np.core.umath 和 np.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#
我们现在不允许在通过 fromstring(readonly-buffer) 创建的数组上将 writeable 标志设置为 True.