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.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
一起弃用。希望覆盖内置 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.PackageLoader
和np.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 渲染。当前格式为实验性格式,可能会更改。
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
添加了关键字参数 prepend 和 append#
新的关键字参数 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
,与通用 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.clip
和 clip
方法检查内存重叠#
现在始终测试这些函数的 out
参数的内存重叠,以避免发生内存重叠时出现损坏的结果。
np.polyfit
中 cov
选项的新值 unscaled
#
已向 np.polyfit
函数的 cov
参数添加了另一个可能的值。使用 cov='unscaled'
将完全禁用协方差矩阵的缩放(类似于在 scipy.optimize.curve_fit
中设置 absolute_sigma=True
)。这在某些情况下很有用,例如权重由 1/sigma 给出,其中 sigma 是(已知的)(高斯分布)数据点的标准误差,在这种情况下,未缩放的矩阵已经是协方差矩阵的正确估计。
标量数值类型的详细文档字符串#
当应用于数值类型(例如 numpy.intc
、numpy.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.take
的 writeable
标志设置为 False
时,np.take
的实现不再对源数组进行不必要的复制。
更多函数支持路径类对象#
np.core.records.fromfile
函数现在除了支持文件对象外,还支持 pathlib.Path
和其他路径类对象。此外,当使用内存映射(mmap_mode
关键字参数)时,np.load
函数现在也支持路径类对象。
改进约简期间 ufunc 恒等式的行为#
通用函数具有一个 .identity
属性,当在空轴上调用 .reduce
时使用。
在本版本中,逻辑二元 ufunc,logical_and、logical_or 和 logical_xor,现在具有 identity
类型为 bool,而以前它们是 int 类型。这恢复了 1.14 版本的行为,即在使用这些 ufunc 对空对象数组进行约简时获得 bool
值,同时保留了 1.15 版本的行为,即在使用 add
和 multiply
等算术 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 例程,确保其在大矩阵上的性能相似。
linspace
、logspace
和 geomspace
的起始和终止数组#
这些函数过去仅限于标量终止值和起始值,但现在可以接受数组,这些数组将被正确广播,并产生在前面附加一个轴的输出。例如,这可以用来获得点集之间的线性插值点。
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)
。
maximum
和minimum
不再发出警告#
作为1.10版中引入的代码的一部分,当使用SSE2语义时,在numpy.maximum
和numpy.minimum
中遇到NaN时,float32
和float64
会设置无效浮点数状态。这导致有时会发出RuntimeWarning。在1.15版本中,我们修复了导致警告更加明显的 inconsistencies。现在不会发出任何警告。
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
#
我们现在不允许将writeable
标志设置为True,该标志用于通过fromstring(readonly-buffer)
创建的数组。