NumPy 2.0.0 发行说明#

NumPy 2.0.0 是自 2006 年以来的第一个主要版本。它是自上次功能发布以来 11 个月开发的成果,由 212 位贡献者通过 1078 个拉取请求完成。它包含大量令人兴奋的新功能以及对 Python 和 C API 的更改。

此主要版本包含在常规次要(功能)版本中无法进行的破坏性更改——包括 ABI 破坏、类型提升规则的更改以及在 1.26.x 中可能未发出弃用警告的 API 更改。除了这些发行说明外,与如何适应 NumPy 2.0 中的更改相关的关键文档包括:

亮点#

此版本的亮点包括:

  • 新功能

    • 一种新的可变长度字符串数据类型 StringDType,以及一个新的 numpy.strings 命名空间,其中包含用于字符串操作的高性能 ufunc,

    • 所有 numpy.fft 函数中对 float32longdouble 的支持,

    • numpy 命名空间中对数组 API 标准的支持。

  • 性能改进

    • 排序函数(sortargsortpartitionargpartition)通过使用 Intel x86-simd-sort 和 Google Highway 库得到了加速,可能会看到大幅(硬件特定)的加速,

    • macOS Accelerate 支持和适用于 macOS >=14 的二进制 wheel,显著提高了 macOS 上线性代数操作的性能,并且 wheel 大小缩小了约 3 倍,

    • numpy.char 固定长度字符串操作已通过实现 ufunc 进行了加速,这些 ufunc 除了支持固定长度字符串数据类型外,还支持 StringDType

    • 一个新的跟踪和自检 API opt_func_info>,用于确定哪些硬件特定的内核可用并将被调度。

    • numpy.save 现在使用 pickle 协议版本 4 来保存具有对象数据类型的数组,这允许 pickle 对象大于 4GB,并为大型数组的保存速度提高了约 5%。

  • Python API 改进

    • 公共 API 和私有 API 之间明确的划分,采用新的模块结构,每个公共函数现在都只在一个位置可用,

    • 移除了许多不推荐的函数和别名。这应该使 NumPy 更易于学习和使用。主命名空间中的对象数量减少了约 10%,numpy.lib 中的对象数量减少了约 80%,

    • 规范的数据类型名称和新的 isdtype 自检函数,

  • C API 改进

  • 改进的行为

    • 通过采用NEP 50改进了类型提升行为。这修复了许多之前通常取决于输入数组数据值而非仅其数据类型的提升导致的意外行为。有关详细信息,请参阅 NEP 和NumPy 2.0 迁移指南,因为此更改可能导致混合数据类型操作的输出数据类型更改和精度降低。

    • Windows 上的默认整数类型现在是 int64 而不是 int32,与在其他平台上的行为保持一致,

    • 数组的最大维度数从 32 更改为 64

  • 文档

此外,NumPy 内部还进行了许多更改,包括继续将代码从 C 迁移到 C++,这将使其在未来更易于改进和维护 NumPy。

“没有免费午餐”定理表明,所有这些 API 和行为改进以及更好的未来可扩展性都伴随着代价。这个代价是:

  1. 向后兼容性。Python 和 C API 都存在大量的破坏性更改。在大多数情况下,会有明确的错误消息通知用户如何调整其代码。但是,也有一些行为更改无法给出此类错误消息——这些情况都包含在下面的“弃用”和“兼容性”部分以及NumPy 2.0 迁移指南中。

    请注意,有一个 ruff 模式可以自动修复 Python 代码中的许多问题。

  2. NumPy ABI 的破坏性更改。因此,使用 NumPy C API 并针对 NumPy 1.xx 版本构建的包的二进制文件将无法与 NumPy 2.0 配合使用。在导入时,此类包将看到 ImportError 并带有关于二进制不兼容的消息。

    可以针对 NumPy 2.0 构建二进制文件,使其在运行时同时适用于 NumPy 2.0 和 1.x。有关更多详细信息,请参阅NumPy 2.0 特定建议

    所有依赖 NumPy ABI 的下游包都被建议发布一个针对 NumPy 2.0 构建的新版本,并验证该版本是否同时适用于 2.0 和 1.26——理想情况下是在 2.0.0rc1(将是 ABI 稳定的)和最终 2.0.0 版本之间,以避免对其用户造成问题。

此版本支持的 Python 版本为 3.9-3.12。

NumPy 2.0 Python API 移除#

  • np.geterrobjnp.seterrobj 以及相关的 ufunc 关键字参数 extobj= 已被移除。所有这些的首选替代方案是使用上下文管理器 with np.errstate():

    (gh-23922)

  • np.cast 已被移除。np.cast[dtype](arg) 的字面替代是 np.asarray(arg, dtype=dtype)

  • np.source 已被移除。首选替代是 inspect.getsource

  • np.lookfor 已被移除。

    (gh-24144)

  • numpy.who 已被移除。作为已移除功能的替代,可以使用 Spyder 或 Jupyter Notebook 等 IDE 中提供的变量浏览器。

    (gh-24321)

  • numpy.exceptions 中存在的警告和异常(例如 ComplexWarningVisibleDeprecationWarning)不再在主命名空间中公开。

  • 主命名空间中移除了多个小众枚举、已过期成员和函数,例如:ERR_*SHIFT_*np.fastCopyAndTransposenp.kernel_versionnp.numarraynp.oldnumericnp.set_numeric_ops

    (gh-24316)

  • numpy/__init__.py 中的 from ... import * 替换为显式导入。因此,这些主命名空间成员被移除:np.FLOATING_POINT_SUPPORTnp.FPE_*np.NINFnp.PINFnp.NZEROnp.PZEROnp.CLIPnp.WRAPnp.WRAPnp.RAISEnp.BUFSIZEnp.UFUNC_BUFSIZE_DEFAULTnp.UFUNC_PYVALS_NAMEnp.ALLOW_THREADSnp.MAXDIMSnp.MAY_SHARE_EXACTnp.MAY_SHARE_BOUNDSadd_newdocnp.add_docstringnp.add_newdoc_ufunc

    (gh-24357)

  • 别名 np.float_ 已被移除。请使用 np.float64

  • 别名 np.complex_ 已被移除。请使用 np.complex128

  • 别名 np.longfloat 已被移除。请使用 np.longdouble

  • 别名 np.singlecomplex 已被移除。请使用 np.complex64

  • 别名 np.cfloat 已被移除。请使用 np.complex128

  • 别名 np.longcomplex 已被移除。请使用 np.clongdouble

  • 别名 np.clongfloat 已被移除。请使用 np.clongdouble

  • 别名 np.string_ 已被移除。请使用 np.bytes_

  • 别名 np.unicode_ 已被移除。请使用 np.str_

  • 别名 np.Inf 已被移除。请使用 np.inf

  • 别名 np.Infinity 已被移除。请使用 np.inf

  • 别名 np.NaN 已被移除。请使用 np.nan

  • 别名 np.infty 已被移除。请使用 np.inf

  • 别名 np.mat 已被移除。请使用 np.asmatrix

  • np.issubclass_ 已被移除。请使用内置的 issubclass

  • np.asfarray 已被移除。请使用带有适当 dtype 的 np.asarray

  • np.set_string_function 已被移除。请改用 np.set_printoptions 并使用格式化程序自定义 NumPy 对象的打印。

  • np.tracemalloc_domain 现在仅可从 np.lib 获得。

  • np.recfromcsvnp.recfromtxt 已从主命名空间中移除。请改用带有逗号分隔符的 np.genfromtxt

  • np.issctypenp.maximum_sctypenp.obj2sctypenp.sctype2charnp.sctypesnp.issubsctype 都已从主命名空间中移除,没有替代,因为它们是小众成员。

  • 已弃用的 np.deprecatenp.deprecate_with_doc 已从主命名空间中移除。请改用 DeprecationWarning

  • 已弃用的 np.safe_eval 已从主命名空间中移除。请改用 ast.literal_eval

    (gh-24376)

  • np.find_common_type 已被移除。请改用 numpy.promote_typesnumpy.result_type。要实现 scalar_types 参数的语义,请使用 numpy.result_type 并传入 00.00j 作为 Python 标量。

  • np.round_ 已被移除。请改用 np.round

  • np.nbytes 已被移除。请改用 np.dtype(<dtype>).itemsize

    (gh-24477)

  • np.compare_chararrays 已从主命名空间中移除。请改用 np.char.compare_chararrays

  • 主命名空间中的 charrarray 已被弃用。目前仍可从 np.char.chararray 导入而不发出弃用警告,但我们计划未来完全弃用并移除 chararray

  • np.format_parser 已从主命名空间中移除。请改用 np.rec.format_parser

    (gh-24587)

  • 已从 np.dtype 中移除七个数据类型字符串别名的支持:int0uint0void0object0str0bytes0bool8

    (gh-24807)

  • 实验性的 numpy.array_api 子模块已被移除。对于常规用途,请使用主 numpy 命名空间;对于合规性测试用例(numpy.array_api 主要用于此目的),请使用单独的 array-api-strict 包。

    (gh-25911)

__array_prepare__ 已被移除#

UFuncs 在执行正常 ufunc 调用(非广义 ufunc、归约等)的计算之前会调用 __array_prepare__。该函数有时也会在某些线性代数函数的结果上替代 __array_wrap__ 被调用。

现在它已被移除。如果您正在使用它,请迁移到 __array_ufunc__ 或依赖 __array_wrap__,后者在所有情况下都会在填充结果数组之后带上下文被调用。在这些代码路径中,__array_wrap__ 现在将传入一个基类,而不是子类数组。

(gh-25105)

弃用#

  • np.compat 已被弃用,因为不再支持 Python 2。

  • numpy.int8 和类似的类将不再支持将超出范围的 Python 整数转换为整数数组。例如,将 255 转换为 int8 将不再返回 -1。numpy.iinfo(dtype) 可用于检查数据类型的机器限制。例如,np.iinfo(np.uint16) 返回 min = 0 和 max = 65535。

    np.array(value).astype(dtype) 将给出所需的结果。

  • np.safe_eval 已被弃用。应改用 ast.literal_eval

    (gh-23830)

  • np.recfromcsvnp.recfromtxtnp.dispnp.get_array_wrapnp.maximum_sctypenp.deprecatenp.deprecate_with_doc 已被弃用。

    (gh-24154)

  • np.trapz 已被弃用。请改用 np.trapezoidscipy.integrate 函数。

  • np.in1d 已被弃用。请改用 np.isin

  • 别名 np.row_stack 已被弃用。请直接使用 np.vstack

    (gh-24445)

  • __array_wrap__ 现在传入 arr, context, return_scalar,并且对不接受所有三个参数的实现的支持已弃用。其签名应为 __array_wrap__(self, arr, context=None, return_scalar=False)

    (gh-25409)

  • 对于 np.cross,二维向量数组的使用已被弃用。请改用三维向量数组。

    (gh-24818)

  • np.dtype("a") 作为 np.dtype(np.bytes_) 的别名已被弃用。请改用 np.dtype("S") 别名。

    (gh-24854)

  • 函数 assert_array_equalassert_array_almost_equal 中关键字参数 xy 的使用已被弃用。请改将前两个参数作为位置参数传递。

    (gh-24978)

numpy.fft 关于参数中带有 None 值的 n-D 变换的弃用#

根据数组 API 标准,已弃用在 fftnifftnrfftnirfftnfft2ifft2rfft2irfft2 中,将 s 参数设置为非 None 值,同时将 axes 参数设置为 None 的做法。要保留当前行为,请对维度为 k 的数组将序列 [0, …, k-1] 传递给 axes

此外,将包含 None 值的数组传递给 s 已被弃用,因为根据 NumPy 文档和数组 API 规范,该参数被记录为接受整数序列。要使用相应 1-D 变换的默认行为,请传递与其 n 参数默认值匹配的值。要使用每个轴的默认行为,可以省略 s 参数。

(gh-25495)

np.linalg.lstsq 现在默认使用新的 rcond#

lstsq 现在使用机器精度乘以 max(M, N) 的新 rcond 值。此前,使用的是机器精度,但发出了 FutureWarning 通知最终会发生此更改。通过传递 rcond=-1 仍然可以实现旧行为。

(gh-25721)

已过期的弃用#

  • np.core.umath_tests 子模块已从公共 API 中移除。(在 NumPy 1.15 中弃用)

    (gh-23809)

  • PyDataMem_SetEventHook 弃用已到期并被移除。请使用 tracemallocnp.lib.tracemalloc_domain 域。(在 NumPy 1.23 中弃用)

    (gh-23921)

  • set_numeric_ops 和 C 函数 PyArray_SetNumericOpsPyArray_GetNumericOps 的弃用已到期,这些函数已被移除。(在 NumPy 1.16 中弃用)

    (gh-23998)

  • fasttakefastclipfastputmask ArrFuncs 的弃用现已最终确定。

  • 已弃用的函数 fastCopyAndTranspose 及其 C 对应项现已移除。

  • PyArray_ScalarFromObject 的弃用现已最终确定。

    (gh-24312)

  • np.msort 已被移除。作为替代,应使用 np.sort(a, axis=0)

    (gh-24494)

  • np.dtype(("f8", 1) 现在将返回形状为 1 的子数组 dtype,而不是非子数组 dtype。

    (gh-25761)

  • 禁止将值分配给 ndarray 的 .data 属性,并将引发错误。

  • np.binary_repr(a, width) 在 width 过小时将引发错误。

  • PyArray_DescrFromType() 中使用 NPY_CHAR 将引发错误,请改用 NPY_STRINGNPY_UNICODENPY_VSTRING

    (gh-25794)

兼容性说明#

loadtxtgenfromtxt 默认编码更改#

loadtxtgenfromtxt 现在都默认使用 encoding=None,这可能主要会修改 converters 的工作方式。现在它们将传入 str 而不是 bytes。明确传递编码以始终获得新或旧行为。对于 genfromtxt,此更改还意味着返回的值现在将是 unicode 字符串而不是字节。

(gh-25158)

f2py 兼容性说明#

  • f2py 将不再接受模糊的 -m.pyf 命令行组合。当传入多个 .pyf 文件时,会引发错误。当 -m.pyf 同时传入时,会发出警告并忽略 -m 提供名称。

    (gh-25181)

  • 由于 f2py.compile() 辅助函数存在内存泄漏,且已被标记为实验性多年,并作为 subprocess.run 的一个薄包装器实现,现已被移除。它也是测试瓶颈之一。有关完整的理由,请参阅 gh-25122。它还使用了几个 np.distutils 功能,这些功能过于脆弱,无法移植到与 meson 配合使用。

  • 建议用户将对 f2py.compile 的调用替换为对 subprocess.run("python", "-m", "numpy.f2py",... 的调用,并使用环境变量与 meson 交互。Native files 也是一个选项。

    (gh-25193)

排序函数行为的微小更改#

由于算法更改和 SIMD 代码的使用,2.0.0 中排序函数(其方法不稳定)的结果可能与 1.26.x 略有不同。这包括 argsortargpartition 的默认方法。

移除了 np.solve 中广播的歧义#

b 的维度比 a 少 1 时,np.solve(a, b) 的广播规则是模糊的。这已通过向后不兼容的方式解决,现在符合 Array API。旧行为可以通过使用 np.solve(a, b[..., None])[..., 0] 来重建。

(gh-25914)

Polynomial 表示的修改#

Polynomial 的表示方法已更新,以在表示中包含域。现在纯文本和 LaTeX 表示是一致的。例如,str(np.polynomial.Polynomial([1, 1], domain=[.1, .2])) 的输出以前是 1.0 + 1.0 x,但现在是 1.0 + 1.0 (-3.0000000000000004 + 20.0 x)

(gh-21760)

C API 更改#

  • PyArray_CGTPyArray_CLTPyArray_CGEPyArray_CLEPyArray_CEQPyArray_CNE 宏已被移除。

  • PyArray_MINPyArray_MAX 已从 ndarraytypes.h 移至 npy_math.h

    (gh-24258)

  • 已公开一个用于处理 numpy.dtypes.StringDType 数组的 C API。这包括用于获取和释放锁定字符串数据访问的互斥体,以及从数组条目打包和解包 UTF-8 字节流的函数。

  • NPY_NTYPES 已更名为 NPY_NTYPES_LEGACY,因为它不包含新的 NumPy 内置 DType。特别是新的字符串 DType 可能无法与处理旧版 DType 的代码正确协同工作。

    (gh-25347)

  • C-API 现在只导出数组访问器的静态内联函数版本(以前这取决于使用“弃用 API”)。虽然我们不鼓励这样做,但仍然可以直接使用结构字段。

    (gh-25789)

  • NumPy 现在定义 PyArray_Pack 来设置单个内存地址。与 PyArray_SETITEM 不同,此函数等同于设置单个数组项,并且不需要 NumPy 数组输入。

    (gh-25954)

  • ->f 槽已从 PyArray_Descr 中移除。如果您使用此槽,请用 PyDataType_GetArrFuncs 替换对其的访问(请参阅其文档和NumPy 2.0 迁移指南)。在某些情况下,使用其他函数,如 PyArray_GETITEM,可能是替代方案。

  • PyArray_GETITEMPyArray_SETITEM 现在需要导入 NumPy API 表才能使用,并且不再在 ndarraytypes.h 中定义。

    (gh-25812)

  • 由于运行时依赖性,访问 dtype 标志的功能定义已从 numpy/ndarraytypes.h 移出,并且仅在包含 numpy/ndarrayobject.h 后才可用,因为它需要 import_array()。这包括 PyDataType_FLAGCHKPyDataType_REFCHKNPY_BEGIN_THREADS_DESCR

  • PyArray_Descr 上的 dtype 标志现在必须通过 PyDataType_FLAGS 内联函数进行访问,才能与 1.x 和 2.x 兼容。此函数在 npy_2_compat.h 中定义,以允许向后移植。大多数或所有用户都应使用 PyDataType_FLAGCHK,该函数在 1.x 上可用且不需要向后移植。Cython 用户应使用 Cython 3。否则,除非他们改用 PyDataType_FLAGCHK,否则访问将通过 Python 进行。

    (gh-25816)

C API 和 Cython 绑定中公开的日期时间功能#

函数 NpyDatetime_ConvertDatetime64ToDatetimeStructNpyDatetime_ConvertDatetimeStructToDatetime64NpyDatetime_ConvertPyDateTimeToDatetimeStructNpyDatetime_GetDatetimeISO8601StrLenNpyDatetime_MakeISO8601DatetimeNpyDatetime_ParseISO8601Datetime 已添加到 C API 中,以方便在外部库中字符串、Python 日期时间与 NumPy 日期时间之间进行转换。

(gh-21199)

广义 ufunc C API 的 const 正确性#

NumPy C API 中用于构建广义 ufunc 的函数(PyUFunc_FromFuncAndDataPyUFunc_FromFuncAndDataAndSignaturePyUFunc_FromFuncAndDataAndSignatureAndIdentity)接受 typesdata 参数,这些参数不会被 NumPy 的内部机制修改。与 namedoc 参数一样,第三方 Python 扩展模块很可能从静态常量提供这些参数。typesdata 参数现在是 const-correct 的:它们分别被声明为 const char *typesvoid *const *data。C 代码应该不受影响,但 C++ 代码可能会受到影响。

(gh-23847)

增大的 NPY_MAXDIMSNPY_MAXARGS,引入了 NPY_RAVEL_AXIS#

NPY_MAXDIMS 现在是 64,您可能需要检查其使用情况。这通常用于栈分配,其中增加应该是安全的。然而,我们通常鼓励移除任何对 NPY_MAXDIMSNPY_MAXARGS 的使用,以便最终完全移除该限制。对于转换助手和镜像 Python 函数的 C-API 函数(例如 take),NPY_MAXDIMS 曾用于表示 axis=None。此类用法必须替换为 NPY_RAVEL_AXIS。另请参阅增加的最大维度数

(gh-25149)

NPY_MAXARGS 不再是常量,以及 PyArrayMultiIterObject 大小变化#

由于 NPY_MAXARGS 增加了,它现在是一个运行时常量,而不再是编译时常量。我们预计几乎没有用户会注意到这一点。但如果用于栈分配,现在必须使用自定义常量替换,并使用 NPY_MAXARGS 作为额外的运行时检查。

sizeof(PyArrayMultiIterObject) 不再包含对象的完整大小。我们预计没有人会注意到此更改。这是为了避免 Cython 相关问题所必需的。

(gh-25271)

自定义旧版用户数据类型所需的更改#

为了改进我们的 DType,不幸的是需要破坏 ABI,这需要对使用 PyArray_RegisterDataType 注册的数据类型进行一些更改。请参阅 PyArray_RegisterDataType 的文档,了解如何调整代码并实现与 1.x 和 2.x 的兼容性。

(gh-25792)

新的公共 DType API#

NEP 42 DType API 的 C 实现现在是公共的。尽管 DType API 已在 NumPy 中发布了几个版本,但它只能在设置了特殊环境变量的会话中使用。现在,可以使用新的 DType API 和正常的 import_array() 机制来导入 numpy C API,从而在 NumPy 之外编写自定义 DType。

有关 API 的更多详细信息,请参阅自定义数据类型。与往常一样,对于新功能,如果您在实现或使用新 DType 时遇到任何 bug,请报告。与 dtypes 协同工作的下游 C 代码很可能需要更新才能与新 DType 正确协同工作。

(gh-25754)

新的 C-API 导入函数#

我们现在添加了 PyArray_ImportNumPyAPIPyUFunc_ImportUFuncAPI 作为静态内联函数,用于导入 NumPy C-API 表。新函数比 import_arrayimport_ufunc 有两个优点:

  • 它们检查导入是否已执行,如果未执行则开销很小,允许有选择地添加它们(尽管在大多数情况下不推荐)。

  • 旧机制是宏而不是函数,其中包含 return 语句。

PyArray_ImportNumPyAPI() 函数包含在 npy_2_compat.h 中,以便更简单地向后移植。

(gh-25866)

通过函数访问结构化数据类型信息#

dtype 结构体字段 c_metadatanamesfieldssubarray 现在必须通过遵循相同名称的新函数(例如 PyDataType_NAMES)进行访问。直接访问这些字段是无效的,因为它们并非存在于所有 PyArray_Descr 实例中。metadata 字段仍然保留,但也应优先使用宏版本。

(gh-25802)

描述符 elsizealignment 访问#

除非只编译支持 NumPy 2 的代码,否则 elsizealignment 字段现在必须通过 PyDataType_ELSIZEPyDataType_SET_ELSIZEPyDataType_ALIGNMENT 进行访问。在描述符附加到数组的情况下,我们建议使用 PyArray_ITEMSIZE,因为它存在于所有 NumPy 版本中。有关更多信息,请参阅PyArray_Descr 结构体已更改

(gh-25943)

NumPy 2.0 C API 移除#

  • npy_interrupt.h 和相应的宏(如 NPY_SIGINT_ON)已被移除。我们建议定期查询 PyErr_CheckSignals()PyOS_InterruptOccurred()(这些目前需要持有 GIL)。

  • noprefix.h 头文件已移除。请将缺失的符号替换为带有前缀的对应项(通常是添加 NPY_npy_)。

    (gh-23919)

  • PyUFunc_GetPyValsPyUFunc_handlefperrPyUFunc_checkfperr 已被移除。如果需要,可以恢复一个向后兼容的新函数来引发浮点错误。移除原因:没有已知用户,并且这些函数会使 with np.errstate() 修复变得更加困难)。

    (gh-23922)

  • numpy/old_defines.h,作为自 NumPy 1.7 以来弃用的 API 的一部分,已被移除。这移除了形如 PyArray_CONSTANT 的宏。脚本 replace_old_macros.sed 可能有助于将其转换为 NPY_CONSTANT 版本。

    (gh-24011)

  • ufunc 结构体的 legacy_inner_loop_selector 成员已被移除,以简化调度系统的改进。没有已知用户覆盖或直接访问此成员。

    (gh-24271)

  • NPY_INTPLTR 已被移除以避免混淆(参见 intp 重新定义)。

    (gh-24888)

  • 高级索引 MapIter 及相关 API 已被移除。其(真正)公共部分未经过充分测试,且只有一个已知用户(Theano)。将其私有化将简化 ufunc.at 的加速、使高级索引更易于维护,并且对于将数组的最大维度数增加到 64 也很重要。如果此 API 对您很重要,请告知我们,以便我们共同寻找解决方案。

    (gh-25138)

  • NPY_MAX_ELSIZE 宏已被移除,因为它只反映内置数值类型且不具有内部用途。

    (gh-25149)

  • PyArray_REFCNTNPY_REFCOUNT 已被移除。请改用 Py_REFCNT

    (gh-25156)

  • PyArrayFlags_TypePyArray_NewFlagsObject 以及 PyArrayFlagsObject 现在是私有的。没有已知的用例;如果需要,请使用 Python API。

  • PyArray_MoveIntoPyArray_CastToPyArray_CastAnyTo 已被移除,请使用 PyArray_CopyInto,如果绝对需要则使用 PyArray_CopyAnyInto(后者执行平面复制)。

  • PyArray_FillObjectArray 已被移除,它唯一的真正用途是实现 np.empty。请创建新的空数组或使用 PyArray_FillWithScalar()(递减现有对象的引用计数)。

  • PyArray_CompareUCS4PyArray_CompareString 已被移除。请使用标准的 C 字符串比较函数。

  • PyArray_ISPYTHON 已被移除,因为它具有误导性,没有已知用例,并且易于替换。

  • PyArray_FieldNames 已被移除,因为它不清楚有什么用处。在某些可能的用例中,它还具有不正确的语义。

  • PyArray_TypestrConvert 已被移除,因为它似乎是一个命名不当且不太可能被任何人使用。如果您知道大小或仅限于少数类型,直接显式使用即可,否则通过 Python 字符串进行。

    (gh-25292)

  • PyDataType_GetDatetimeMetaData 已被移除,自 NumPy 1.7 以来它实际上就没有任何作用。

    (gh-25802)

  • PyArray_GetCastFunc 已被移除。请注意,自定义旧版用户数据类型仍然可以提供 castfunc 作为其实现,但现在已移除对它们的任何访问。这是因为 NumPy 多年来从未在内部使用过这些。如果您使用简单的数值类型,请直接使用 C 类型转换。如果您需要替代方案,请告知我们,以便我们可以创建新的 API,例如 PyArray_CastBuffer(),它可以根据 NumPy 版本使用旧的或新的类型转换函数。

    (gh-25161)

新功能#

np.add 已扩展以支持 unicodebytes dtype。#

新增 bitwise_count 函数#

此新函数计算数字中1位的数量。bitwise_count 适用于所有 NumPy 整型和类整型对象。

>>> a = np.array([2**i - 1 for i in range(16)])
>>> np.bitwise_count(a)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
      dtype=uint8)

(gh-19355)

macOS Accelerate 支持,包括 ILP64#

已在 macOS 13.3 中添加了对更新的 Accelerate BLAS/LAPACK 库的支持,包括 ILP64(64位整数)支持。这带来了 arm64 支持,并使常用线性代数运算的性能显著提升,最高可达10倍。如果在构建时选择了 Accelerate,或者未明确选择 BLAS 库,则在可用时将自动使用 13.3+ 版本。

(gh-24053)

也提供了二进制 wheel 包。在 macOS >=14.0 上,从 PyPI 安装 NumPy 的用户将获得针对 Accelerate 而非 OpenBLAS 构建的 wheel 包。

(gh-25255)

分位数和百分位数函数新增权重选项#

weights 关键字现已可用于 quantilepercentilenanquantilenanpercentile。仅 method="inverted_cdf" 支持权重。

(gh-24254)

改进的 CPU 优化追踪#

NumPy 库中新增了一种追踪机制,能够追踪每个优化函数(即使用硬件特定 SIMD 指令的函数)所启用的目标。通过此增强功能,可以精确监控已调度函数所启用的 CPU 调度目标。

新命名为 opt_func_info 的函数已添加到新命名空间 numpy.lib.introspect 中,提供了此追踪功能。此函数允许您根据函数名称和数据类型签名检索有关已启用目标的信息。

(gh-24420)

f2py 新增 Meson 后端#

f2py 在编译模式(即 f2py -c)下现在接受 --backend meson 选项。这是 Python >=3.12 的默认选项。对于旧版本的 Python,f2py 仍将默认使用 --backend distutils

为了在实际用例中支持此功能,在编译模式下,f2py 接受一个或多个 --dep 标志,该标志映射到 meson 后端中的 dependency() 调用,而在 distutils 后端中则不执行任何操作。

对于仅将 f2py 用作代码生成器(即不带 -c)的用户,没有变化。

(gh-24532)

f2py 新增 bind(c) 支持#

函数和子例程都可以使用 bind(c) 进行标注。f2py 将处理正确的类型映射,并为其他 C 接口保留唯一的标签。

注意: 根据设计,f2py 绑定不接受 bind(c, name = 'routine_name_other_than_fortran_routine'),因为带 namebind(c) 旨在仅保证 C 和 Fortran 中的名称相同,而非 Python 和 Fortran 中的名称相同。

(gh-24555)

多个测试函数新增 strict 选项#

strict 关键字现已可用于 assert_allcloseassert_equalassert_array_less。将 strict=True 设置为 True 将禁用标量的广播行为,并确保输入数组具有相同的数据类型。

(gh-24680, gh-24770, gh-24775)

新增 np.core.umath.findnp.core.umath.rfind UFunc#

新增两个 findrfind UFunc,它们作用于 Unicode 或字节字符串,并用于 np.char。它们的操作类似于 str.findstr.rfind

(gh-24868)

numpy.linalg 的 diagonaltrace#

已添加 numpy.linalg.diagonalnumpy.linalg.trace,它们是与数组 API 标准兼容的 numpy.diagonalnumpy.trace 变体。它们的区别在于定义二维子数组的默认轴选择。

(gh-24887)

新增 longulong dtype#

已添加 numpy.longnumpy.ulong 作为 NumPy 整数,它们映射到 C 语言的 longunsigned long。在 NumPy 1.24 之前,numpy.long 是 Python int 的别名。

(gh-24922)

numpy.linalg 的 svdvals#

已添加 numpy.linalg.svdvals。它计算(一组)矩阵的奇异值。执行 np.svdvals(x) 等同于调用 np.svd(x, compute_uv=False, hermitian=False)。此函数与数组 API 标准兼容。

(gh-24940)

新增 isdtype 函数#

已添加 numpy.isdtype,以提供一种符合数组 API 标准的规范方式来分类 NumPy 的 dtype。

(gh-25054)

新增 astype 函数#

已添加 numpy.astype,以提供一种与数组 API 标准兼容的替代 numpy.ndarray.astype 方法。

(gh-25079)

数组 API 兼容函数的别名#

新增了13个现有函数的别名,以提高与数组 API 标准的兼容性

  • 三角函数:acos, acosh, asin, asinh, atan, atanh, atan2

  • 位运算:bitwise_left_shift, bitwise_invert, bitwise_right_shift

  • 其他:concat, permute_dims, pow

  • numpy.linalg 中:tensordot, matmul

(gh-25086)

新增 unique_* 函数#

已添加 unique_allunique_countsunique_inverseunique_values 函数。它们提供了具有不同标志集的 unique 功能。它们与数组 API 标准兼容,并且由于它们返回的数组数量不依赖于输入参数的值,因此更容易用于 JIT 编译。

(gh-25088)

ndarray 的矩阵转置支持#

NumPy 现在支持计算数组(或数组堆栈)的矩阵转置。矩阵转置等同于交换数组的最后两个轴。np.ndarraynp.ma.MaskedArray 现在都暴露了 .mT 属性,并且有一个匹配的新函数 numpy.matrix_transpose

(gh-23762)

numpy.linalg 的数组 API 兼容函数#

为提高与数组 API 标准的兼容性,numpy.linalg 新增了六个函数和两个别名

var 和 std 函数新增 correction 参数#

已向 varstd 添加 correction 参数,它是一个与数组 API 标准兼容的 ddof 替代参数。由于这两个参数用途相似,因此一次只能提供其中一个。

(gh-25169)

ndarray.devicendarray.to_device#

已向 numpy.ndarray 添加了 ndarray.device 属性和 ndarray.to_device 方法,以兼容数组 API 标准。

此外,device 仅关键字参数已添加到以下函数:asarrayarangeemptyempty_likeeyefullfull_likelinspaceonesones_likezeroszeros_like

对于所有这些新参数,仅支持 device="cpu"

(gh-25233)

NumPy 已新增 StringDType#

我们新增了一种变宽 UTF-8 编码的字符串数据类型,实现了“Python 字符串的 NumPy 数组”,包括支持用户提供的缺失数据哨兵。它旨在替代使用对象 dtype 的 Python 字符串数组和缺失数据哨兵。有关更多详细信息,请参阅 NEP 55文档

(gh-25347)

cholesky 和 pinv 新增关键字#

已分别向 numpy.linalg.choleskynumpy.linalg.pinv 添加了 upperrtol 关键字,以提高数组 API 标准兼容性。

对于 pinv,如果未指定 rcondrtol,则使用 rcond 的默认值。我们计划未来弃用并移除 rcond

(gh-25388)

sort、argsort 和 linalg.matrix_rank 新增关键字#

已新增关键字参数以提高数组 API 标准兼容性

(gh-25437)

字符串 ufunc 的新命名空间 numpy.strings#

NumPy 现在将一些字符串操作实现为 ufunc。旧的 np.char 命名空间仍然可用,并且在可能的情况下,该命名空间中的字符串操作函数已更新为使用新的 ufunc,从而显著提高了其性能。

在可能的情况下,我们建议更新代码以使用 np.strings 中的函数,而不是 np.char。将来,我们可能会弃用 np.char 而倾向于使用 np.strings

(gh-25463)

numpy.fft 支持不同精度和就地计算#

numpy.fft 中的各种 FFT 例程现在根据输入精度,以 float、double 或 long double 精度进行本地计算,而不是始终以 double 精度计算。因此,对于单精度,计算的精度会降低,而对于长双精度,精度会提高。输出数组的数据类型现在将相应调整。

此外,所有 FFT 例程都新增了一个 out 参数,可用于就地计算。

(gh-25536)

configtool 和 pkg-config 支持#

新增了一个 numpy-config CLI 脚本,可以查询 NumPy 版本以及使用 NumPy C API 所需的编译标志。这将使构建系统能够更好地支持将 NumPy 作为依赖项使用。此外,NumPy 现在包含了 numpy.pc pkg-config 文件。为了查找其位置以配合 PKG_CONFIG_PATH 使用,请使用 numpy-config --pkgconfigdir

(gh-25730)

主命名空间中的数组 API 标准支持#

numpy 命名空间现在支持数组 API 标准。有关详细信息,请参阅 数组 API 标准兼容性

(gh-25911)

改进#

字符串现在受到 anyall 和逻辑 ufunc 的支持。#

memmap 的形状参数支持整数序列#

numpy.memmap 现在可以使用任何整数序列作为 shape 参数创建,例如整数列表或 NumPy 数组。以前,只有元组和 int 类型才能在不引发错误的情况下使用。

(gh-23729)

errstate 现在更快且上下文安全#

numpy.errstate 上下文管理器/装饰器现在更快、更安全。以前,它不是上下文安全的,并且(罕见地)存在线程安全问题。

(gh-23936)

AArch64 快速排序速度通过使用 Highway 的 VQSort 得到提升#

首次引入 Google Highway 库,在 AArch64 上使用 VQSort。在某些情况下,执行时间提高了多达 16 倍,请参阅 PR 以获取基准测试结果。未来将扩展到其他平台。

(gh-24018)

复数类型 - 底层 C 类型变更#

  • 所有 NumPy 复数类型的底层 C 类型已更改为使用 C99 复数类型。

  • 虽然此更改不影响复数类型的内存布局,但它更改了用于直接检索或写入复数实部或虚部的 API,因为直接字段访问(如 c.realc.imag)不再是选项。您现在可以使用 numpy/npy_math.h 中提供的实用程序来执行这些操作,如下所示:

    npy_cdouble c;
    npy_csetreal(&c, 1.0);
    npy_csetimag(&c, 0.0);
    printf("%d + %di\n", npy_creal(c), npy_cimag(c));
    
  • 为了简化跨版本兼容性,已添加了等效的宏和兼容性层,下游包可以使用它们继续支持 NumPy 1.x 和 2.x。有关更多信息,请参阅 复数支持

  • numpy/npy_common.h 现在包含 complex.h,这意味着 complex 现在是一个保留关键字。

(gh-24085)

f2py 新增 iso_c_binding 支持并改进了公共块#

以前,用户必须定义自己的自定义 f2cmap 文件才能使用 Fortran2003 iso_c_binding 内置模块定义的类型映射。这些类型映射现在由 f2py 原生支持

(gh-24555)

f2py 现在支持处理具有模块中 kind 规范的 common 块。这进一步扩展了 iso_fortran_enviso_c_binding 等内置函数的可操作性。

(gh-25186)

自动对 assert_equal 等函数的第三个参数调用 str#

现在,assert_equal 等函数的第三个参数会自动调用 str。这样它就模拟了内置的 assert 语句,其中 assert_equal(a, b, obj) 的作用类似于 assert a == b, obj

(gh-24877)

iscloseallclose 中对类数组 atol/rtol 的支持#

iscloseallclose 中的关键字 atolrtol 现在同时接受标量和数组。如果给定数组,则必须广播到前两个数组参数的形状。

(gh-24878)

测试函数中一致的失败消息#

以前,某些 numpy.testing 断言会打印将实际结果和期望结果称为 xy 的消息。现在,这些值始终被称为 ACTUALDESIRED

(gh-24931)

n-D FFT 变换允许 s[i] == -1#

s[i] == -1 时,fftnifftnrfftnirfftnfft2ifft2rfft2irfft2 函数现在沿轴 i 使用整个输入数组,与数组 API 标准保持一致。

(gh-25495)

为受限 API 保护 PyArrayScalar_VALPyUnicodeScalarObject#

PyUnicodeScalarObject 持有 PyUnicodeObject,在使用 Py_LIMITED_API 时不可用。添加保护以隐藏它,从而也使 PyArrayScalar_VAL 宏隐藏。

(gh-25531)

变更#

  • np.gradient() 现在返回一个元组而不是列表,使返回值不可变。

    (gh-23861)

  • np.errstate 现在完全上下文安全且线程安全,因此只能进入一次。

  • np.setbufsize 现在与 np.errstate() 绑定:退出 np.errstate 上下文也将重置 bufsize

    (gh-23936)

  • 已引入新的公共子模块 np.lib.array_utils,它目前包含三个函数:byte_bounds(从 np.lib.utils 移出)、normalize_axis_tuplenormalize_axis_index

    (gh-24540)

  • 引入 numpy.bool 作为 NumPy 布尔 dtype 的新规范名称,并使 numpy.bool_ 成为它的别名。请注意,在 NumPy 1.24 之前,np.bool 是 Python 内置 bool 的别名。新名称有助于数组 API 标准兼容性,并且是一个更直观的名称。

    (gh-25080)

  • dtype.flags 值以前存储为有符号整数。这意味着对齐的 dtype 结构体标志导致设置了负标志(-128 而不是 128)。此标志现在存储为无符号(正)数。手动检查标志的代码可能需要进行调整。这可能包括使用 Cython 0.29.x 编译的代码。

    (gh-25816)

NumPy 标量表示发生变化#

根据 NEP 51,标量表示已更新为包含类型信息,以避免与 Python 标量混淆。

标量现在打印为 np.float64(3.0) 而不是仅 3.0。这可能会干扰存储数字表示(例如,到文件)的工作流,使其难以读取。它们应存储为显式字符串,例如使用 str()f"{scalar!s}"。目前,受影响的用户可以使用 np.set_printoptions(legacy="1.25") 来获得旧行为(可能有一些例外)。如果测试代码片段,下游项目的文档可能需要更大的更新。我们正在为 doctest-plus 开发工具以促进更新。

(gh-22449)

NumPy 字符串的真值判断发生变化#

以前,NumPy 字符串在定义字符串是 True 还是 False 方面存在不一致,并且该定义与 Python 使用的定义不匹配。现在,当字符串非空时,它们被视为 True;当字符串为空时,它们被视为 False。这改变了以下几种情况:

  • 以前,从字符串到布尔值的类型转换大致等同于 string_array.astype(np.int64).astype(bool),这意味着只有有效的整数才能进行类型转换。现在,字符串 "0" 将被视为 True,因为它不为空。如果您需要旧行为,可以使用上述步骤(首先转换为整数)或 string_array == "0"(如果输入始终为 01)。要在旧 NumPy 版本上获取新结果,请使用 string_array != ""

  • np.nonzero(string_array) 以前忽略了空白字符,因此只包含空白字符的字符串被视为 False。现在,空白字符被视为 True

此更改不影响 np.loadtxtnp.fromstringnp.genfromtxt。前两个仍然使用整数定义,而 genfromtxt 继续匹配 "true"(不区分大小写)。但是,如果 np.bool_ 用作转换器,结果将发生变化。

此更改确实影响 np.fromregex,因为它使用直接赋值。

(gh-23871)

var 和 std 函数新增 mean 关键字#

通常,当需要标准差时,也需要均值。方差和均值也是如此。到目前为止,均值都会计算两次,此处为 varstd 函数引入的更改允许将预计算的均值作为关键字参数传入。有关详细信息和说明加速的示例,请参阅文档字符串。

(gh-24126)

构建带时区的 datetime64 时移除弃用警告#

当提供的日期时间字符串中包含时区时,numpy.datetime64 方法现在会发出 UserWarning 而不是 DeprecationWarning

(gh-24193)

64 位 Windows 上默认整数 dtype 现为 64 位#

默认 NumPy 整数现在在所有 64 位系统上都是 64 位,因为 Windows 上历史性的 32 位默认值是常见问题源。大多数用户应该不会注意到这一点。主要问题可能出现在与用 C 等编译语言编写的库进行接口的代码中。有关更多信息,请参阅 Windows 默认整数

(gh-24224)

numpy.core 重命名为 numpy._core#

访问 numpy.core 现在会发出 DeprecationWarning。在实践中,我们发现大多数下游对 numpy.core 的使用是为了访问主 numpy 命名空间中可用的功能。如果由于某种原因您正在使用 numpy.core 中主 numpy 命名空间中不可用的功能,这意味着您可能正在使用 NumPy 的私有内部功能。您仍然可以通过 numpy._core 访问这些内部功能而不会收到弃用警告,但我们不对 NumPy 内部功能提供任何向后兼容性保证。如果您认为存在错误并且需要公开某些内容,请提出问题。

(gh-24634)

以前通过 NPY_RELAXED_STRIDES_DEBUG 环境变量或 -Drelaxed-strides-debug 配置设置标志启用的“relaxed strides”调试构建选项已被移除。

(gh-24717)

np.intp/np.uintp 的重新定义(几乎没有变化)#

由于这些类型的实际使用几乎总是与 size_t/Py_ssize_t 的使用匹配,因此这现在是 C 语言中的定义。以前,它匹配 intptr_tuintptr_t,这通常是微妙的错误。这对于绝大多数机器没有影响,因为这些类型的大小仅在极少数特殊平台上有所不同。

然而,这意味着

  • 指针可能不再必然适合 intp 类型数组。但是,pP 字符代码仍然可以使用。

  • 通过 PyArray_DescrFromType('p'),仍然可以以跨平台的方式在 C 语言中创建 intptr_tuintptr_t 类型数组。

  • 引入了新的字符代码 nN

  • 现在,在解析为 npy_intp 类型参数时使用 Python C-API 函数是正确的。

(gh-24888)

numpy.fft.helper 设为私有#

numpy.fft.helper 已重命名为 numpy.fft._helper,以表明它是一个私有子模块。它导出的所有公共函数都应从 numpy.fft 访问。

(gh-24945)

numpy.linalg.linalg 设为私有#

numpy.linalg.linalg 已重命名为 numpy.linalg._linalg,以表明它是一个私有子模块。它导出的所有公共函数都应从 numpy.linalg 访问。

(gh-24946)

越界轴不再等同于 axis=None#

在某些情况下,axis=32 或对于 concatenate 而言,任何大值都与 axis=None 相同。除了 concatenate 之外,这已被弃用。任何越界轴值现在都将引发错误,请确保使用 axis=None

(gh-25149)

arrayasarray 构造函数中 copy 关键字的新含义#

现在 numpy.arraynumpy.asarray 支持 copy 参数的三个值

  • None - 仅在必要时创建副本。

  • True - 始终创建副本。

  • False - 从不创建副本。如果需要副本,则引发 ValueError

False 的含义已更改,如果需要副本,它现在会引发异常。

(gh-25168)

__array__ 特殊方法现在接受 copy 关键字参数。#

copy 将被设置为非默认值的情况下(例如在调用 np.asarray(some_object, copy=False) 时),NumPy 会将 copy 传递给 __array__ 特殊方法。目前,如果在此之后引发意外关键字参数错误,NumPy 将打印警告并尝试不带 copy 关键字参数重新执行。实现 __array__ 协议的对象的实现应该接受一个 copy 关键字参数,其含义与传递给 numpy.arraynumpy.asarray 时相同。

(gh-25168)

使用带逗号的字符串初始化 numpy.dtype 的清理#

带逗号的字符串的解释略有改变,尾随逗号现在将始终创建一个结构化 dtype。例如,以前 np.dtype("i")np.dtype("i,") 被视为相同,现在 np.dtype("i,") 将创建一个结构化 dtype,带有一个字段。这类似于 np.dtype("i,i") 创建一个带有两个字段的结构化 dtype,并使行为与元组的预期行为保持一致。

同时,使用括号括起来的单个数字表示子数组形状(例如在 np.dtype("(2)i,") 中)已被弃用。相反,应该使用 np.dtype("(2,)i")np.dtype("2i")。最终,使用括号中的数字将引发异常,就像不带逗号的初始化(例如 np.dtype("(2)i"))一样。

(gh-25434)

复数符号计算方式变更#

按照数组 API 标准,复数符号现在计算为 z / |z|(而不是以前那种不太合理的,取实部符号,除非实部为零,此时返回虚部符号的情况)。与实数类似,如果 z==0 则返回零。

(gh-25441)

返回数组列表的函数的返回类型#

返回 ndarray 列表的函数已更改为返回 ndarray 元组。当返回一系列数组时始终返回元组,这使得 Numba 等 JIT 编译器以及在某些情况下的静态类型检查器更容易支持这些函数。更改的函数包括:atleast_1datleast_2datleast_3dbroadcast_arraysmeshgridogridhistogramdd

多维输入时 np.unique return_inverse 的形状#

当多维输入与 return_inverse=True 一起传递给 np.unique 时,unique_inverse 输出的形状现在使得当 axis=None 时,输入可以直接使用 np.take(unique, unique_inverse) 重建,否则使用 np.take_along_axis(unique, unique_inverse, axis=axis) 重建。

注意

此更改在 2.0.1 中被恢复,axis=None 除外。正确的重建始终是 np.take(unique, unique_inverse, axis=axis)。当需要支持 2.0.0 时,请在代码中添加 unique_inverse.reshape(-1)

(gh-25553, gh-25570)

anyall 对于对象数组返回布尔值#

anyall 函数及方法现在也为对象数组返回布尔值。以前,它们会进行归约操作,其行为类似于 Python 的 orand 运算符,求值结果为其中一个参数。您可以使用 np.logical_or.reducenp.logical_and.reduce 来实现之前的行为。

(gh-25712)

不能对 Python int、float 或 complex 调用 np.can_cast#

np.can_cast 不再能用 Python int、float 或 complex 实例调用。这是因为 NEP 50 规定 can_cast 的结果不得依赖于传入的值。不幸的是,对于 Python 标量,类型转换是应被视为 "same_kind" 还是 "safe" 可能取决于上下文和值,因此目前尚未实现此功能。在某些情况下,这意味着您可能需要添加一个特定路径:if type(obj) in (int, float, complex): ...

(gh-26393)