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。
此版本进行了大量重构,并包含许多错误修复、改进的代码组织和更好的跨平台兼容性。并非所有这些改进对用户都可见,但它们应该有助于使未来的维护工作更轻松。
亮点#
实验性(仅限 opt-in)支持覆盖 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 已废弃。它们存在 bug 且未文档化,将在 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.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 结构体相同,而之前它等于类型的大小。对于许多用户(例如在 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
关键字参数被接受用于指定要展开的数组形状。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:
新功能#
已向 histogram
添加集成平方误差 (ISE) 估计器#
这种优化 bin 数量的方法(bins='stone'
)是 Scott's rule 的推广。Scott's rule 假定分布近似正态,而 ISE 是一种基于交叉验证的非参数方法。
为 np.loadtxt
添加 max_rows
关键字#
numpy.loadtxt
中新增的关键字 max_rows
用于设置在 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 notebooks 中以 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 已与当前的 upstream 工作同步。
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
在编译 Fortran 扩展时,始终覆盖而非追加 LDFLAGS 和其他类似的环境变量。现在,如果将 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 进行浮点状态错误报告。以前我们有一个损坏的默认设置,有时不会报告下溢、上溢和无效浮点运算。现在,只要非 glibc 发行版(如 Alpine Linux)提供 fenv.h,我们就可以支持它们。
加速大型数组的 np.block
#
大型数组(大于 512 * 512
)现在使用基于将数据直接复制到结果数组的适当切片中的阻塞算法。这显著加快了这些大型数组的速度,特别是对于沿超过 2 个维度进行阻塞的数组。
arr.ctypes.data_as(...)
持有对 arr 的引用#
以前,调用者负责在指针的生命周期内保持数组的活跃。
加速只读数组的 np.take
#
当源数组的 writeable
标志设置为 False
时,np.take
的实现不再对源数组进行不必要的复制。
支持更多函数中的路径类对象#
np.core.records.fromfile
函数现在除了文件对象外,还支持 pathlib.Path
和其他路径类对象。此外,np.load
函数在使用内存映射(mmap_mode
关键字参数)时也支持路径类对象。
ufunc 归约过程中标识行为的改进#
通用函数(ufunc)具有一个 .identity
属性,当在空轴上调用 .reduce
时使用它。
自此版本起,逻辑二元 ufuncs,logical_and、logical_or 和 logical_xor,现在具有 bool 类型的 identity
,而以前它们是 int 类型。这恢复了 1.14 版本在使用这些 ufuncs 归约空对象数组时获得 bool
值的行为,同时保留了 1.15 版本在使用 add
和 multiply
等算术 ufuncs 归约空对象数组时获得 int
值的行为。
此外,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
、logspace
和 geomspace
的起始和终止数组#
这些函数以前仅限于标量起始和终止值,但现在可以接受数组,这些数组将正确广播并生成一个在其前面附加一个轴的输出。例如,这可用于获取点集之间的线性插值点。
CI 扩展了额外服务#
我们现在使用额外的免费 CI 服务,感谢提供以下服务的公司:
通过 codecov.io 进行代码覆盖率测试
通过 shippable.com 进行 Arm 测试
Azure Pipelines 上的额外测试运行
这些是除了我们继续使用 travis、appveyor(用于 wheels)和 LGTM 之外的。
变更#
比较 ufunc 现在将报错而不是返回 NotImplemented#
以前,诸如 np.equal
的比较 ufunc 如果其参数具有结构化 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)
,而是使用 chisq/(M-N-2)
进行缩放,其中 M 是数据点数量,N 是参数数量。这种缩放与 scipy.optimize.curve_fit
等其他拟合程序不一致,现已更改为 chisq/(M-N)
。
maximum
和 minimum
不再发出警告#
作为 1.10 中引入代码的一部分,当在 numpy.maximum
和 numpy.minimum
中遇到 Nan 时,float32
和 float64在使>用 SSE2 语义时会设置无效浮点状态。这有时会导致发出 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。