NumPy 1.25.0 发行说明#

NumPy 1.25.0 版本继续进行改进 dtype 处理和提升,提高执行速度以及阐明文档的工作. 还在为未来的 NumPy 2.0.0 版本做准备,从而导致大量新的和过期的弃用. 重点是:

  • 支持 MUSL,现在有 MUSL wheels.

  • 支持 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_typenumpy.promote_types 替换其使用.大多数用户将 find_common_type 的第二个 scalar_types 参数保留为 [] ,在这种情况下, np.result_typenp.promote_types 都更快且更强大.当不使用 scalar_types 时,主要区别在于替换会故意将非本地字节顺序转换为本地字节顺序.此外, find_common_type 返回 object dtype 而不是失败的提升.当输入不全是数字时,这会导致差异.重要的是,这也发生在例如 timedelta/datetime 上,因为 NumPy 升级规则目前有时会令人惊讶.

    scalar_types 参数不是 [] 时,情况会更复杂.在大多数情况下,使用 np.result_type 并传递 Python 值 0 , 0.00j 与在 scalar_types 中使用 int , floatcomplex 具有相同的结果.

    当构造 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.macharnp.finfo.machar 已被删除.

    ( gh-22638 )

  • 当 dtype 不是数字(并且未定义正数)时, +arr 现在会引发错误.

    ( gh-22998 )

  • 现在必须将序列传递到堆叠系列函数( stack , vstack , hstack , dstackcolumn_stack )中.

    ( gh-23019 )

  • np.clip 现在默认为同类转换.回退到不安全的转换已在 NumPy 1.17 中弃用.

    ( gh-23403 )

  • np.clip 现在将传播作为 minmax 传递的 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]) ).

    • 当值从根本上不可比较(例如,具有不同的 dtypes)时,返回一个包含所有 True 或所有 False 的数组.一个例子是 np.array(["a"]) == np.array([1]) .

      这模仿了 Python 在比较不兼容的类型(如 "a" == 1"a" != 1 )时返回 FalseTrue 的行为.长期以来,这些都给出了 DeprecationWarningFutureWarning .

    ( 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 , isposinfisneginf 函数允许使用 y= 作为 out= 的(已弃用的)别名.不再支持此功能.

    ( gh-23376 )

兼容性说明#

  • busday_count 方法现在可以正确处理 begindates 在时间上晚于 enddates 的情况.以前,即使文档声明它始终被排除在外,也包括 enddates .

    ( gh-23229 )

  • 以前,当使用 np.equalnp.not_equal 比较日期时间和时间增量时,numpy 允许使用 casting="unsafe" 进行比较.此操作现在失败.使用 dtype kwarg 强制输出 dtype 可以使操作成功,但我们不建议这样做.

    ( gh-22707 )

  • 当使用 np.load 从文件句柄加载数据时,如果句柄位于文件末尾,就像通过重复调用 np.load 读取多个数组时可能发生的那样,numpy 以前在 allow_pickle=False 时引发 ValueError ,在 allow_pickle=True 时引发 OSError .现在,在这两种情况下,它都会引发 EOFError .

    ( gh-23105 )

np.pad 使用 mode=wrap 模式时,填充数据为原始数据的严格倍数#

基于早期版本中使用 mode="wrap"pad 代码,当填充尺寸大于初始数组时,将返回不同的结果.

np.pad 现在使用 mode=wrap 模式时,始终使用原始数据的严格倍数填充空间,即使填充尺寸大于初始数组.

( gh-22575 )

移除了 Cython long_tulong_t#

long_tulong_tlonglong_tulonglong_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 ,请使用纯 longnpy_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.ufuncwhere 关键字参数是 numpy.ndarray 的子类,或者是一个定义了 numpy.class.__array_ufunc__ 的 duck 类型,它可以像输入和输出参数一样,使用相同的机制覆盖 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 的 C API 相同,因此生成的程序将与 NumPy 1.16 兼容(从 C-API 的角度来看).此默认值将在未来的非错误修复版本中增加.您仍然可以针对较旧的 NumPy 版本进行编译,并在较新的版本上运行.

有关更多详细信息,请参见 对于下游软件包的作者 .

( gh-23528 )

新特性#

np.einsum 现在接受 object dtype 的数组#

该代码路径将在 object dtype 数组上调用 python 运算符,很像 np.dotnp.matmul .

( 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 函数返回 NamedTuples#

现在,返回元组的 np.linalg 函数返回 namedtuples.这些函数是 eig() , eigh() , qr() , slogdet()svd() .在这些函数使用某些关键字参数返回非元组(例如 svd(compute_uv=False) )的情况下,返回类型不会更改.

( gh-22786 )

np.char 中的字符串函数与 NEP 42 自定义 dtypes 兼容#

现在可以将表示 Unicode 字符串或字节字符串的自定义 dtypes 传递给 np.char 中的字符串函数.

( gh-22863 )

可以从字符串抽象 dtype 类创建字符串 dtype 实例#

现在可以在不使用 dtype 的字符串名称的情况下创建具有大小的字符串 dtype 实例.例如, type(np.dtype('U'))(8) 将创建一个等效于 np.dtype('U8') 的 dtype.此功能在编写处理字符串 dtype 类的通用代码时最有用.

( gh-22963 )

现在支持 Fujitsu C/C++ 编译器#

已添加对 Fujitsu 编译器的支持.要使用 Fujitsu 编译器进行构建,请运行:

python setup.py build -c fujitsu

现在支持 SSL2#

已添加对 SSL2 的支持.SSL2 是一个提供 OpenBLAS 兼容 GEMM 函数的库.要启用 SSL2,需要编辑 site.cfg 并使用 Fujitsu 编译器进行构建.请参阅 site.cfg.example.

( gh-22982 )

改进#

NDArrayOperatorsMixin 指定它没有 __slots__#

NDArrayOperatorsMixin 类现在指定它不包含 __slots__ ,从而确保子类现在可以在 Python 中使用此功能.

( gh-23113 )

修复复数零的幂#

现在, np.power 为复数的 0^{非零} 返回不同的结果.请注意,仅当指数的实部大于零时才定义该值.以前,除非虚部严格为零,否则返回 NaN.返回值是 0+0j0-0j .

( gh-18535 )

新的 DTypePromotionError#

NumPy 现在有一个新的 DTypePromotionError ,当两个 dtypes 不能提升为通用类型时使用,例如:

np.result_type("M8[s]", np.complex128)

引发这个新的异常.

( gh-22707 )

np.show_config 使用来自 Meson 的信息#

构建和系统信息现在包含来自 Meson 的信息. np.show_config 现在有一个新的可选参数 mode 来帮助自定义输出.

( gh-22769 )

修复了使用参数 prepend/append 调用 np.ma.diff 时不保留掩码的问题.#

现在,使用参数 prepend 和/或 append 调用 np.ma.diff 会返回一个保留输入掩码的 MaskedArray .

以前,会返回一个没有掩码的 MaskedArray .

( gh-22776 )

修正了 Cython 中 NumPy C-API 的错误处理#

许多为在 Cython 中使用而定义的 NumPy C 函数都缺少正确的错误指示符,例如 except -1except * .现在已经添加了这些.

( 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 参数#

如果 base 参数可以广播到 startstop 参数,那么它可以是类数组.

( gh-23275 )

np.ma.dot() 现在支持非 2d 数组#

以前,只有当 ab 都是 2d 时, np.ma.dot() 才有效.现在,它也适用于非 2d 数组以及 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.savenp.savez 在保存之前删除元数据.

( gh-23371 )

numpy.lib.recfunctions.structured_to_unstructured 在更多情况下返回视图#

如果字段之间的步幅是恒定的, structured_to_unstructured 现在返回一个视图.在此之前,字段之间的填充或反向字段将导致复制.此更改仅适用于 ndarray , memmaprecarray .对于所有其他数组子类,行为保持不变.

( gh-23652 )

有符号整数和无符号整数总是可以正确比较#

uint64int64 在 NumPy 中混合使用时,NumPy 通常会将它们都提升为 float64 .这种行为可能会引起争议,但对于比较 == , <= 来说,这会让人感到困惑,因为返回的结果可能不正确,但转换是被隐藏的,因为结果是一个布尔值.NumPy 现在将通过避免转换为浮点数来返回正确的结果.

( gh-23713 )

性能改进和更改#

在启用 AVX-512 的处理器上, np.argsort 更快#

用于 np.argsort 的 32 位和 64 位快速排序算法在支持 AVX-512 指令集的处理器上速度提高了 6 倍.

感谢 Intel corporation 赞助这项工作.

( gh-23707 )

在启用 AVX-512 的处理器上, np.sort 更快#

对于支持 AVX-512 指令集的处理器,16 位和 64 位数据类型的快速排序速度分别提高了 15 倍和 9 倍.

感谢 Intel corporation 赞助这项工作.

( gh-22315 )

__array_function__ 机制现在更快#

NumPy 中大多数函数的开销现在更小,尤其是在使用关键字参数时.此更改显着加快了许多简单的函数调用.

( gh-23020 )

ufunc.at 可以快得多#

通用的 ufunc.at 可以快 9 倍.加速的条件是:

  • 操作数是对齐的

  • 没有类型转换

如果 ufunc 在满足上述条件的 1 维参数上具有适当的索引循环,则 ufunc.at 可以快 60 倍(额外的 7 倍加速).已将适当的索引循环添加到 add , subtract , multiply , floor_divide , maximum , minimum , fmaxfmin .

内部逻辑类似于用于常规 ufunc 的逻辑,后者也有快速路径.

感谢 D. E. Shaw group 赞助这项工作.

( 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 )