NumPy 1.19.0 发行说明#
此 NumPy 版本标志着大量技术债务的清除:已移除对 Python 2 的支持,许多弃用已被终止,并且文档得到了改进。随机模块的完善工作也在有条不紊地进行,包括错误修复和更好的 Cython 可用性。
此版本支持的 Python 版本是 3.6-3.8。下游开发人员应使用 Cython >= 0.29.16 来支持 Python 3.8,并使用 OpenBLAS >= 3.7 以避免 Skylake 架构上的问题。
亮点#
Python 代码和 C 代码都放弃了与 Python < 3.6 版本(包括 Python 2)的代码兼容性。
numpy.compat中的填充层将保留以支持第三方包,但它们可能会在未来版本中弃用。请注意,由于使用了 f-字符串,1.19.x *不会*与早期版本的 Python 编译。(gh-15233)
已终止的弃用#
numpy.insert 和 numpy.delete 不再允许在 0d 数组上传递轴参数#
这结束了从 1.9 版本开始的弃用,即当向 0d 数组上的 ~numpy.insert 和 ~numpy.delete 调用传递 axis 参数时,axis 和 obj 参数以及索引将被完全忽略。在这些情况下,insert(arr, "nonsense", 42, axis=0) 实际上会覆盖整个数组,而 delete(arr, "nonsense", axis=0) 将是 arr.copy()
现在,在 0d 数组上传递 axis 会引发 ~numpy.AxisError。
(gh-15802)
numpy.delete 不再忽略越界索引#
这结束了 1.8 和 1.9 版本的弃用,当时 np.delete 会忽略索引序列中的负项和越界项。这与其在传递单个索引时的行为不一致。
现在,越界项会引发 IndexError,负项则从末尾开始索引。
(gh-15804)
numpy.insert 和 numpy.delete 不再接受非整数索引#
这结束了从 1.9 开始的弃用,当时允许非整数索引序列并将其强制转换为整数。现在,传递非整数索引序列会引发 IndexError,就像传递单个非整数标量一样。
(gh-15805)
numpy.delete 不再将布尔索引强制转换为整数#
这结束了 1.8 版本的弃用,当时 np.delete 会将作为索引参数传递的布尔数组和标量强制转换为整数索引。现在的行为是将布尔数组视为掩码,并对布尔标量引发错误。
(gh-15815)
兼容性说明#
更改了 numpy.random.Generator.dirichlet 的随机变量流#
通过在 max(alpha) < 0.1 时使用不同的算法,修复了 Dirichlet 分布随机变量生成中 alpha 值较小时的 bug。由于此更改,在这种情况下,由 dirichlet 生成的变量流将与以前的版本不同。
(gh-14924)
PyArray_ConvertToCommonType 中的标量提升#
PyArray_ConvertToCommonType 中混合标量和数组的提升已更改为遵循 np.result_type 使用的规则。这意味着诸如 (1000, np.array([1], dtype=np.uint8))) 之类的输入现在将返回 uint16 dtypes。在大多数情况下,行为不变。请注意,通常不鼓励使用此 C-API 函数。这也修复了 np.choose 在这方面与 NumPy 的其余部分行为相同的问题。
(gh-14933)
Fasttake 和 fastputmask 槽位被弃用并设为 NULL#
fasttake 和 fastputmask 槽位现在永不使用,并且必须始终设置为 NULL。这不会导致行为上的改变。但是,如果用户 dtype 设置了其中一个,则会发出 DeprecationWarning。
(gh-14942)
np.ediff1d 使用 to_end 和 to_begin 的强制类型转换行为#
np.ediff1d 现在对其附加的 to_end 和 to_begin 参数使用 "same_kind" 强制类型转换规则。这确保了类型安全,除非输入数组的整数类型小于 to_begin 或 to_end。在极少数情况下,其行为将比以前在 1.16 和 1.17 版本中更严格。这对于解决浮点 NaN 的问题是必要的。
(gh-14981)
将空类数组对象转换为 NumPy 数组#
实现“类数组”接口(即实现 obj.__array__()、obj.__array_interface__、obj.__array_struct__ 或 Python 缓冲区接口)且 len(obj) == 0 的对象,如果它们也是序列(例如 Pandas 对象),现在在转换为数组时将始终正确保留其形状。如果此类对象以前的形状是 (0, 1),则它可以转换为形状为 (0,) 的数组(丢失第一个 0 之后的所有维度)。
(gh-14995)
移除了 multiarray.int_asbuffer#
作为持续移除 Python 2 兼容性的一部分,multiarray.int_asbuffer 已被移除。在 Python 3 上,它会引发 NotImplementedError 且内部未使用。预计 Python 3 不会有此方法的下游用例。
(gh-15229)
numpy.distutils.compat 已被移除#
此模块仅包含函数 get_exception(),其用法如下
try:
...
except Exception:
e = get_exception()
其目的是处理 Python 2.6 中引入的语法更改,从 except Exception, e: 到 except Exception as e:,这意味着它仅对支持 Python 2.5 及更早版本的代码库是必需的。
(gh-15255)
issubdtype 不再将 float 解释为 np.floating#
numpy.issubdtype 自 NumPy 1.14 以来就有一个 FutureWarning,现在已过期。这意味着,当第二个参数既不是数据类型也不是 NumPy 标量类型(例如字符串或 Python 类型如 int 或 float)时,某些输入现在将与传入 np.dtype(arg2).type 的结果一致。这使得结果符合预期,并在某些以前返回 true 的情况下导致错误结果。
(gh-15773)
更改标量 round 的输出以与 Python 保持一致#
__round__ 魔术方法以及随后的 Python 内置函数 round 的输出已更改为 Python int,以便在不带参数调用时与在 Python float 对象上调用保持一致。以前,它会返回传入的 np.dtype 的标量。
(gh-15840)
numpy.ndarray 构造函数不再将 strides=() 解释为 strides=None#
前者已改为具有将 numpy.ndarray.strides 设置为 () 的预期含义,而后者继续导致步幅自动选择。
(gh-15882)
C 级别的字符串到日期时间转换已更改#
从字符串进行的 C 级别转换已简化。此更改也修复了字符串到日期时间和时间差的转换,使其行为正确(即像使用 string_arr.astype("M8") 进行的 Python 转换一样,而以前的转换行为则像 string_arr.astype(np.int_).astype("M8"))。这仅影响使用低级 C-API 进行单标量值手动转换(而不是完整的数组转换)或使用例如 PyArray_GetCastFunc 的代码,因此不应影响绝大多数用户。
(gh-16068)
小种子 SeedSequence 不再与生成冲突#
小种子(小于 2**96)以前会隐式地用 0 填充到 128 位,即内部熵池的大小。当生成时,生成键会在 0 填充之前被连接。由于第一个生成键是 (0,),所以在生成之前的小种子会创建与第一个生成的 SeedSequence 相同的状态。现在,种子会在连接生成键之前显式地用 0 填充到内部池大小。生成的 SeedSequences 将产生与上一个版本不同的结果。未生成的 SeedSequences 仍将产生相同的结果。
(gh-16551)
弃用#
弃用不规则输入的自动 dtype=object#
根据 NEP 34,调用 np.array([[1, [1, 2, 3]]) 将发出 DeprecationWarning。用户应明确使用 dtype=object 以避免警告。
(gh-15119)
在 numpy.rec 中,向工厂函数传递 shape=0 已被弃用#
0 被视为特殊情况,并在以下函数中别名为 None
numpy.core.records.fromarraysnumpy.core.records.fromrecordsnumpy.core.records.fromstringnumpy.core.records.fromfile
未来,0 将不再是特殊情况,并将像其他整数一样被视为数组长度。
(gh-15217)
可能未使用的 C-API 函数的弃用#
以下 C-API 函数可能未使用,已被弃用
PyArray_GetArrayParamsFromObjectPyUFunc_GenericFunctionPyUFunc_SetUsesArraysAsData
在大多数情况下,PyArray_GetArrayParamsFromObject 应该被转换为数组所取代,而 PyUFunc_GenericFunction 可以被 PyObject_Call 取代(详见文档)。
(gh-15427)
将某些类型转换为 dtypes 已被弃用#
标量类型的超类,如 np.integer、np.generic 或 np.inexact,在转换为 dtype(或在 dtype 关键字参数中使用)时,现在会发出弃用警告。原因在于 np.integer 被转换为 np.int_,而预期它代表*任何*整数(例如 int8、int16 等)。例如,dtype=np.floating 目前与 dtype=np.float64 完全相同,尽管 np.float32 也是 np.floating 的子类。
(gh-15534)
弃用 np.complexfloating 标量的 round 方法#
__round__ 魔术方法以及随后的 Python 内置函数 round 在复数标量上已被弃用。这不影响 np.round。
(gh-15840)
numpy.ndarray.tostring() 已弃用,推荐使用 tobytes()#
~numpy.ndarray.tobytes 自 1.9 版本发布以来一直存在,但在此版本之前 ~numpy.ndarray.tostring 没有发出警告。发出警告的改变使 NumPy 与内置 array.array 具有相同名称的方法保持一致。
(gh-15867)
C API 更改#
更好地支持 API 函数中的 const 维度#
以下函数现在接受一个 npy_intp 常量数组
PyArray_BroadcastToShapePyArray_IntTupleFromIntpPyArray_OverflowMultiplyList
以前,调用者必须强制转换掉 const 属性才能调用这些函数。
(gh-15251)
限定 UFunc 内部循环为 const#
UFuncGenericFunction 现在期望指向 const dimension 和 strides 的指针作为参数。这意味着内部循环不再可能修改 dimension 或 strides。此更改会导致 incompatible-pointer-types 警告,强制用户要么忽略编译器警告,要么对自己的循环签名进行 const 限定。
(gh-15355)
新特性#
numpy.frompyfunc 现在接受 identity 参数#
这允许在生成的 ufunc 上设置 numpy.ufunc.identity 属性,这意味着它可用于 numpy.ufunc.reduce 的空调用和多维调用。
(gh-8255)
np.str_ 标量现在支持缓冲区协议#
np.str_ 数组始终以 UCS4 存储,因此相应的标量现在通过缓冲区接口公开此功能,这意味着 memoryview(np.str_('test')) 现在可以工作了。
(gh-15385)
numpy.copy 的 subok 选项#
在 numpy.copy 中添加了一个新的 kwarg subok,允许用户切换 numpy.copy 在处理数组子类时的行为。默认值是 False,这与以前 NumPy 版本的 numpy.copy 行为一致。要使用 numpy.copy 创建一个保留数组子类的副本,请调用 np.copy(arr, subok=True)。此新增功能更好地说明了 numpy.copy 的默认行为与 numpy.ndarray.copy 方法不同,后者默认遵循数组子类。
(gh-15685)
numpy.linalg.multi_dot 现在接受 out 参数#
out 可用于避免创建 numpy.linalg.multidot 计算的最终产品的不必要副本。
(gh-15715)
numpy.count_nonzero 的 keepdims 参数#
keepdims 参数已添加到 numpy.count_nonzero 中。该参数的含义与 numpy.sum 或 numpy.mean 等归约函数中的含义相同。
(gh-15870)
numpy.array_equal 的 equal_nan 参数#
关键字参数 equal_nan 已添加到 numpy.array_equal 中。equal_nan 是一个布尔值,用于切换 nan 值在比较中是否被视为相等(默认值为 False)。这与 numpy.isclose 和 numpy.allclose 等相关函数中使用的 API 匹配。
(gh-16128)
改进#
改进 CPU 特性检测#
替换了 npy_cpu_supports(这是一个特定于 gcc 的用于测试 AVX 支持的机制),改为使用更通用的函数 npy_cpu_init 和 npy_cpu_have,并通过 NPY_CPU_HAVE C 宏以及 Python 级别的 __cpu_features__ 字典公开结果。
(gh-13421)
在 64 位平台上的备用 lapack_lite 中使用 64 位整数大小#
在 64 位平台上的备用 LAPACK 库(当系统没有安装 LAPACK 时使用)中使用 64 位整数大小,使其能够处理大型数组的线性代数。
(gh-15218)
当输入为 np.float64 时,使用 AVX512 内在函数实现 np.exp#
当输入为 np.float64 时,使用 AVX512 内在函数实现 np.exp,这可以将 np.exp 与 np.float64 输入的性能提高 5-7 倍。_multiarray_umath.so 模块在 linux64 上增加了约 63 KB。
(gh-15648)
禁用 madvise 大页内存的能力#
在 Linux 上,NumPy 以前曾添加了对 madvise 大页内存的支持,这可以提高超大型数组的性能。不幸的是,在较旧的内核版本上,这导致了性能下降,因此默认情况下,在 4.6 版本之前的内核上已禁用此支持。要覆盖默认设置,您可以使用环境变量
NUMPY_MADVISE_HUGEPAGE=0
或将其设置为 1 以强制启用支持。请注意,这仅在操作系统设置为使用 madvise 透明大页内存时才会有所不同。
(gh-15769)
numpy.einsum 在下标列表中接受 NumPy int64 类型#
现在,当 numpy.einsum 将 NumPy int64 数组作为其下标列表传递时,不再抛出类型错误。
(gh-16080)
np.logaddexp2.identity 更改为 -inf#
ufunc ~numpy.logaddexp2 现在具有 -inf 的 identity,允许在空序列上调用它。这与 ~numpy.logaddexp 的 identity 匹配。
(gh-16102)
更改#
移除对 __array__ 额外参数的处理#
自 NumPy 0.4 以来,代码中一直存在一个针对 __array__(dtype=None, context=None) 的双参数变体的代码路径和测试。当调用 ufunc(op) 或 ufunc.reduce(op) 且 op.__array__ 存在时,它会被激活。然而,该变体没有文档,其用途也不清楚。它已被移除。
(gh-15118)
numpy.random._bit_generator 移至 numpy.random.bit_generator#
为了将 numpy.random.BitGenerator 和 numpy.random.SeedSequence 公开给 Cython,_bitgenerator 模块现在已作为 numpy.random.bit_generator 公开
通过 pxd 文件提供对随机分布的 Cython 访问#
c_distributions.pxd 通过 Cython 提供了对许多随机分布背后的 C 函数的访问,使其易于使用和扩展。
(gh-15463)
修复了 numpy.random.multivariate_normal 中 eigh 和 cholesky 方法的问题#
以前,当传递 method='eigh' 或 method='cholesky' 时,numpy.random.multivariate_normal 会从错误的分布生成样本。现在这个问题已修复。
(gh-15872)
修复了 MT19937.jumped 中的跳转实现#
此修复改变了经跳转的 MT19937 生成器所产生的流。它不影响使用 RandomState 或直接初始化的 MT19937 所产生的流。
MT19937 跳转代码的翻译包含了一个反向的循环顺序。MT19937.jumped 符合松本真(Makoto Matsumoto)的 Horner 和滑动窗口(Sliding Window)跳转方法的原始实现。
(gh-16153)