NumPy 1.25.0 版本说明#
NumPy 1.25.0 版本继续改进数据类型处理和提升、提高执行速度以及改进文档说明的工作。同时也为未来的 NumPy 2.0.0 版本做准备,导致大量新的和已过期的弃用声明。主要亮点包括:
支持 MUSL,现在有 MUSL 轮子。
支持 Fujitsu C/C++ 编译器。
einsum 现在支持对象数组。
支持就地矩阵乘法 (
@=
)。
当 Python 3.12 发布时,我们将发布 NumPy 1.26。这是必要的,因为 Python 3.12 已删除 distutils,我们将切换到使用 meson 进行未来的构建。下一个主要版本将是 NumPy 2.0.0。我们计划 2.0 系列仍将支持针对早期 NumPy 版本构建的下游项目。
此版本支持的 Python 版本为 3.9-3.11。
弃用声明#
np.core.MachAr
已弃用。它是私有 API。一般应将np.core
中定义的名称视为私有。(gh-22638)
np.finfo(None)
已弃用。(gh-23011)
np.round_
已弃用。请改用 np.round。(gh-23302)
np.product
已弃用。请改用 np.prod。(gh-23314)
np.cumproduct
已弃用。请改用 np.cumprod。(gh-23314)
np.sometrue
已弃用。请改用 np.any。(gh-23314)
np.alltrue
已弃用。请改用 np.all。(gh-23314)
只有 ndim-0 数组被视为标量。NumPy 过去将所有大小为 1 的数组(例如
np.array([3.14])
)视为标量。将来,这将仅限于 ndim 为 0 的数组(例如np.array(3.14)
)。以下表达式将报告弃用警告a = np.array([3.14]) float(a) # better: a[0] to get the numpy.float or a.item() b = np.array([[3.14]]) c = numpy.random.rand(10) c[0] = b # better: c[0] = b[0, 0]
(gh-10615)
np.find_common_type
已弃用。numpy.find_common_type 现已弃用,其使用应替换为numpy.result_type
或numpy.promote_types
。大多数用户将find_common_type
的第二个scalar_types
参数保留为[]
,在这种情况下,np.result_type
和np.promote_types
都更快且更健壮。当不使用scalar_types
时,主要区别在于替换有意将非原生字节序转换为原生字节序。此外,find_common_type
返回object
数据类型而不是提升失败。当输入并非全是数字时,这会导致差异。重要的是,这也会发生在例如 timedelta/datetime 上,对于这些情况,NumPy 提升规则目前有时令人惊讶。当
scalar_types
参数不是[]
时,情况会更复杂。在大多数情况下,使用np.result_type
并传递 Python 值0
、0.0
或0j
与在 scalar_types 中使用int
、float
或complex
的结果相同。当构建
scalar_types
时,np.result_type
是正确的替换,并且可以传递标量值,例如np.float32(0.0)
。传递 0 之外的值可能会导致值检查行为(np.find_common_type
从未使用过,NEP 50 未来可能会改变)。在这种情况下,行为的主要可能变化是,当数组类型是有符号整数而标量类型是无符号整数时。如果您不确定如何替换
scalar_types
的用法,或者非数值 dtype 可能出现时,请随时打开 NumPy issue 寻求帮助。(gh-22539)
已过期的弃用声明#
np.core.machar
和np.finfo.machar
已移除。(gh-22638)
当数据类型不是数值类型(并且正数未定义)时,
+arr
现在将引发错误。(gh-22998)
现在必须将序列传递到堆叠系列函数中 (
stack
、vstack
、hstack
、dstack
和column_stack
)。(gh-23019)
np.clip
现在默认为同类类型转换。在 NumPy 1.17 中,回退到不安全转换已被弃用。(gh-23403)
np.clip
现在将传播作为min
或max
传递的np.nan
值。以前,标量 NaN 通常被忽略。这在 NumPy 1.17 中已被弃用。(gh-23403)
np.dual
子模块已被移除。(gh-23480)
NumPy 现在始终忽略类数组的序列行为(定义数组协议之一)。(弃用始于 NumPy 1.20)
(gh-23660)
在
astype
或数组创建函数(如asarray
)中转换为子数组 dtype 时的利基FutureWarning
现已完成。行为现在始终与子数组 dtype 包装到单个字段中的行为相同(这是以前的解决方法)。(自 NumPy 1.20 起为 FutureWarning)(gh-23666)
==
和!=
警告已完成。==
和!=
运算符在数组上现在始终引发在比较过程中发生的错误,例如当数组具有不相容的形状时 (
np.array([1, 2]) == np.array([1, 2, 3])
)。当值根本不可比较(例如具有不同的数据类型)时,返回全是
True
或全是False
的数组。一个例子是np.array(["a"]) == np.array([1])
。这模仿了 Python 在比较不相容类型(如
"a" == 1
和"a" != 1
)时返回False
和True
的行为。长期以来,这些会给出DeprecationWarning
或FutureWarning
。
(gh-22707)
Nose 支持已移除。NumPy 在 2018 年切换到使用 pytest,而 nose 多年来一直未维护。我们保留了 NumPy 的 nose 支持,以避免破坏可能仍在使用它且尚未切换到 pytest 或其他测试框架的下游项目。随着 Python 3.12 的到来,未修补的 nose 将引发错误。是时候继续前进了。
移除的装饰器:
raises
slow
setastest
skipif
knownfailif
deprecated
parametrize
_needs_refcount
不要将这些与名称相似的 pytest 版本混淆,例如 pytest.mark.slow、pytest.mark.skipif、pytest.mark.parametrize。
移除的函数:
Tester
import_nose
run_module_suite
(gh-23041)
numpy.testing.utils
shim 已移除。自 2019 年以来,从numpy.testing.utils
shim 导入已被弃用,该 shim 现已移除。所有导入都应直接从numpy.testing
进行。(gh-23060)
禁用分派的的环境变量已被移除。对
NUMPY_EXPERIMENTAL_ARRAY_FUNCTION
环境变量的支持已被移除。此变量禁用使用__array_function__
的分派。(gh-23376)
已移除对
y=
作为out=
别名的支持。fix
、isposinf
和isneginf
函数允许使用y=
作为out=
的(已弃用)别名。此功能不再受支持。(gh-23376)
兼容性说明#
busday_count
方法现在可以正确处理begindates
晚于enddates
的情况。以前,即使文档说明总是排除enddates
,它也会被包含。(gh-23229)
在使用
np.equal
或np.not_equal
比较日期时间和时间增量时,NumPy以前允许使用casting="unsafe"
进行比较。此操作现在会失败。可以使用dtype
关键字参数强制输出dtype,但这并不推荐。(gh-22707)
使用
np.load
从文件句柄加载数据时,如果句柄位于文件末尾(例如,通过重复调用np.load
读取多个数组时可能会发生这种情况),则NumPy以前会在allow_pickle=False
时引发ValueError
,在allow_pickle=True
时引发OSError
。现在,这两种情况下都会引发EOFError
。(gh-23105)
使用mode=wrap
的np.pad
使用原始数据的严格倍数进行填充#
基于早期版本的pad
且使用mode="wrap"
的代码,当填充大小大于初始数组时,将返回不同的结果。
使用mode=wrap
的np.pad
现在始终使用原始数据的严格倍数填充空间,即使填充大小大于初始数组。
(gh-22575)
已移除Cython long_t
和ulong_t
#
long_t
和ulong_t
是longlong_t
和ulonglong_t
的别名,并且容易混淆(Python 2 的残留)。此更改可能会导致错误。
'long_t' is not a type identifier
'ulong_t' is not a type identifier
我们建议使用位大小类型,例如cnp.int64_t
或cnp.intp_t
(在32位系统上为32位,在64位系统上为64位)(这与索引最兼容)。如果需要C long
,请使用普通的long
或npy_long
。cnp.int_t
也是long
(NumPy的默认整数)。但是,在64位Windows上long
是32位,我们可能希望即使在NumPy中也调整这一点。(如果您对此感到好奇,请随时联系NumPy开发者。)
(gh-22637)
更改了传递给ufunc
的错误axes
参数的错误消息和类型#
将错误的axes
值传递给ufunc(..., axes=[...])`
时的错误消息和类型已更改。消息现在更能说明问题,如果值不匹配,则会引发AxisError
。对于无效的输入类型,仍然会引发TypeError
。
(gh-22675)
定义了__array_ufunc__
的类数组现在可以覆盖用作where
的ufunc#
如果numpy.ufunc
的where
关键字参数是numpy.ndarray
的子类,或者是一个定义了numpy.class.__array_ufunc__
的鸭子类型,它可以使用与输入和输出参数相同的机制来覆盖ufunc的行为。请注意,为了使此方法正常工作,where.__array_ufunc__
实现将必须解包where
参数,将其传递到ufunc
的默认实现中,或者对于numpy.ndarray
子类在使用super().__array_ufunc__
之前。
(gh-23240)
现在默认情况下,针对 NumPy C API 的编译向后兼容#
NumPy现在默认公开C-API的向后兼容子集。这使得使用oldest-supported-numpy
变得不必要。库可以覆盖默认的最小版本以兼容使用
#define NPY_TARGET_VERSION NPY_1_22_API_VERSION
在包含NumPy之前,或者通过向编译器传递等效的-D
选项。NumPy 1.25的默认值为NPY_1_19_API_VERSION
。因为NumPy 1.19 C API与NumPy 1.16相同,所以生成的程序将与NumPy 1.16兼容(从C-API的角度来看)。此默认值将在未来的非错误修复版本中增加。您仍然可以针对旧版本的NumPy编译并在较新版本上运行。
更多详细信息,请参见面向下游包作者。
(gh-23528)
新功能#
np.einsum
现在接受具有object
dtype 的数组#
代码路径将像np.dot
和np.matmul
一样,在object dtype数组上调用Python运算符。
(gh-18053)
添加了对就地矩阵乘法的支持#
现在可以通过@=
运算符执行就地矩阵乘法。
>>> import numpy as np
>>> a = np.arange(6).reshape(3, 2)
>>> print(a)
[[0 1]
[2 3]
[4 5]]
>>> b = np.ones((2, 2), dtype=int)
>>> a @= b
>>> print(a)
[[1 1]
[5 5]
[9 9]]
(gh-21120)
添加了NPY_ENABLE_CPU_FEATURES
环境变量#
用户现在可以通过指定NPY_ENABLE_CPU_FEATURES环境变量来选择只启用运行时构建的CPU功能的子集。请注意,这些指定的特性必须位于基线之外,因为总是假设这些特性。如果尝试启用CPU不支持的特性,或者NumPy没有构建的特性,则会引发错误。
(gh-22137)
NumPy现在具有np.exceptions
命名空间#
NumPy现在有一个专门的命名空间,使大多数异常和警告可用。所有这些都保留在主命名空间中,尽管将来可能会缓慢移动一些。这样做的主要原因是提高可发现性并添加未来的异常。
(gh-22644)
np.linalg
函数返回命名元组#
现在,返回元组的np.linalg
函数将返回命名元组。这些函数包括eig()
、eigh()
、qr()
、slogdet()
和svd()
。在这些函数使用某些关键字参数(例如svd(compute_uv=False)
)返回非元组的情况下,返回类型保持不变。
(gh-22786)
np.char
中的字符串函数与NEP 42自定义dtype兼容#
现在,可以将表示unicode字符串或字节字符串的自定义dtype传递给np.char
中的字符串函数。
(gh-22863)
可以从字符串抽象dtype类创建字符串dtype实例#
现在可以创建一个指定大小的字符串dtype实例,而无需使用dtype的字符串名称。例如,type(np.dtype('U'))(8)
将创建一个等效于np.dtype('U8')
的dtype。此功能在编写处理字符串dtype类的通用代码时最为有用。
(gh-22963)
现在支持富士通C/C++编译器#
已添加对富士通编译器的支持。要使用富士通编译器进行构建,请运行:
python setup.py build -c fujitsu
现在支持SSL2#
已添加对SSL2的支持。SSL2是一个提供与OpenBLAS兼容的GEMM函数的库。要启用SSL2,需要编辑site.cfg并使用富士通编译器进行构建。请参阅site.cfg.example。
(gh-22982)
改进#
NDArrayOperatorsMixin
指定它没有__slots__
#
NDArrayOperatorsMixin
类现在指定它不包含__slots__
,确保子类现在可以在Python中使用此功能。
(gh-23113)
修复复数零的幂#
对于复数,np.power
现在对0^{非零}
返回不同的结果。请注意,只有当指数的实部大于零时,该值才被定义。以前,除非虚部严格为零,否则返回NaN。返回值为0+0j
或0-0j
。
(gh-18535)
新的DTypePromotionError
#
NumPy现在有一个新的DTypePromotionError
,当两个dtype无法提升到一个公共dtype时使用,例如
np.result_type("M8[s]", np.complex128)
引发此新异常。
(gh-22707)
np.show_config使用来自Meson的信息#
构建和系统信息现在包含来自Meson的信息。np.show_config现在有一个新的可选参数mode
来帮助自定义输出。
(gh-22769)
修复np.ma.diff
在使用prepend/append参数调用时不保留掩码#
使用prepend和/或append参数调用np.ma.diff
现在将返回一个保留输入掩码的MaskedArray
。
以前,返回的是没有掩码的MaskedArray
。
(gh-22776)
修正Cython中NumPy C-API的错误处理#
许多为在Cython中使用而定义的NumPy C函数都缺少正确的错误指示符,例如except -1
或except *
。这些现在都已添加。
(gh-22997)
直接生成随机数生成器的能力#
numpy.random.Generator.spawn
现在允许通过numpy.random.SeedSequence.spawn
机制直接生成新的独立子生成器。numpy.random.BitGenerator.spawn
对底层位生成器执行相同的操作。
此外,numpy.random.BitGenerator.seed_seq
现在可以直接访问用于初始化位生成器的种子序列。例如,这允许
seed = 0x2e09b90939db40c400f8f22dae617151
rng = np.random.default_rng(seed)
child_rng1, child_rng2 = rng.spawn(2)
# safely use rng, child_rng1, and child_rng2
以前,如果不显式传递SeedSequence
,这很难做到。请参阅numpy.random.SeedSequence
了解更多信息。
(gh-23195)
numpy.logspace
现在支持非标量base
参数#
如果numpy.logspace
的base
参数可以与start
和stop
参数进行广播,则它现在可以是类似数组的。
(gh-23275)
np.ma.dot()
现在支持非二维数组#
以前np.ma.dot()
仅当a
和b
都是二维时才有效。现在它也适用于非二维数组,就像np.dot()
一样。
(gh-23322)
在repr中显式显示.npz文件的键#
NpzFile
打印时显示已加载.npz文件的键。
>>> npzfile = np.load('arr.npz')
>>> npzfile
NpzFile 'arr.npz' with keys arr_0, arr_1, arr_2, arr_3, arr_4...
(gh-23357)
NumPy现在在np.dtypes
中公开了DType类#
新的numpy.dtypes
模块现在公开了DType类,并将包含未来的与dtype相关的功能。大多数用户不需要直接使用这些类。
(gh-23358)
在保存到.npy或.npz文件之前删除dtype元数据#
当前,包含具有元数据的dtype的表的*.npy
文件无法读取回来。现在,np.save和np.savez在保存之前删除元数据。
(gh-23371)
numpy.lib.recfunctions.structured_to_unstructured
在更多情况下返回视图#
如果字段之间的步长是常数,structured_to_unstructured
现在将返回一个视图。之前,字段之间的填充或反转字段会导致复制。此更改仅适用于ndarray
、memmap
和recarray
。对于所有其他数组子类,行为保持不变。
(gh-23652)
有符号整数和无符号整数始终正确比较#
当在NumPy中混合使用uint64
和int64
时,NumPy通常会将两者都提升为float64
。这种行为可能会引起争议,但对于比较==
、<=
来说是令人困惑的,因为返回的结果可能是错误的,但转换是隐藏的,因为结果是布尔值。NumPy现在将通过避免转换为浮点数来为这些返回正确的结果。
(gh-23713)
性能改进和更改#
在支持 AVX-512 指令集的处理器上加速 np.argsort
#
用于 np.argsort
的 32 位和 64 位快速排序算法在支持 AVX-512 指令集的处理器上速度提升高达 6 倍。
感谢 英特尔公司 为这项工作提供赞助。
(gh-23707)
在支持 AVX-512 指令集的处理器上加速 np.sort
#
针对 16 位和 64 位数据类型的快速排序算法在支持 AVX-512 指令集的处理器上速度提升高达 15 倍和 9 倍。
感谢 英特尔公司 为这项工作提供赞助。
(gh-22315)
__array_function__
机制现在快得多#
NumPy 中大多数函数的开销现在更小,尤其是在使用关键字参数时。此更改显着加快了许多简单的函数调用。
(gh-23020)
ufunc.at
速度可能快得多#
通用 ufunc.at
速度最多可提高 9 倍。此速度提升的条件:
操作数已对齐
无需类型转换
如果 ufunc 在满足上述条件的一维参数上具有适当的索引循环,则 ufunc.at
的速度最多可提高 60 倍(额外提高 7 倍)。已将适当的索引循环添加到 add
、subtract
、multiply
、floor_divide
、maximum
、minimum
、fmax
和 fmin
。
内部逻辑类似于常规 ufunc 使用的逻辑,后者也具有快速路径。
感谢 D. E. Shaw 集团 为这项工作提供赞助。
(gh-23136)
加快 NpzFile
的成员测试#
如果成功,NpzFile
的成员测试将不再解压缩存档。
(gh-23661)
更改#
np.r_[]
和 np.c_[]
与某些标量值#
在极少数情况下,主要使用带有标量的 np.r_
会导致不同的结果。以下重点介绍了主要潜在变化:
>>> np.r_[np.arange(5, dtype=np.uint8), -1].dtype
int16 # rather than the default integer (int64 or int32)
>>> np.r_[np.arange(5, dtype=np.int8), 255]
array([ 0, 1, 2, 3, 4, 255], dtype=int16)
第二个示例返回的结果为
array([ 0, 1, 2, 3, 4, -1], dtype=int8)
第一个示例是由于带符号整数标量与无符号整数数组,而第二个示例是由于 255
不适合 int8
,并且 NumPy 当前正在检查值以使其工作。(请注意,由于 NEP 50,第二个示例预计将来会发生变化;届时它将引发错误。)
(gh-22539)
大多数 NumPy 函数都封装在 C 可调用函数中#
为了加快 __array_function__
的调度,大多数 NumPy 函数现在都封装在 C 可调用函数中,而不是合适的 Python 函数或 C 方法。它们看起来和感觉与以前一样(像 Python 函数),这只会提高性能和用户体验(更清晰的回溯)。但是,如果此更改由于某种原因混淆了您的程序,请告知 NumPy 开发人员。
(gh-23020)
C++ 标准库的使用#
NumPy 构建现在依赖于 C++ 标准库,因为 numpy.core._multiarray_umath
扩展与 C++ 链接器链接。
(gh-23601)