
NumPy 2.x 新变化np.positive 与一元 运算符现已支持布尔数组【免费下载链接】numpyThe fundamental package for scientific computing with Python.项目地址: https://gitcode.com/gh_mirrors/nu/numpy导读本文围绕 NumPy 发布说明release note中一条 API 改进展开np.positive及一元运算符不再对布尔数组抛出_UFuncNoLoopError而是正式注册了布尔类型的内核循环loop。读完本文你将理解这次改动的前后行为差异、背后的 ufunc 注册机制类型解析器与循环分派、对应的源码位置与测试覆盖以及它对既有代码迁移带来的影响。改动摘要在 NumPy 的doc/release/upcoming_changes/32100.improvement.rst中记录了一项行为改进np.positive与一元运算符现在为布尔数组注册了计算循环np.positive(np.array([True, False]))现在可以直接返回[True, False]而不再抛出_UFuncNoLoopError。这是典型的 ufunc 类型循环loop扩充布尔类型?被加入positive的可用输入类型集合使一元正号运算符在布尔数组上有了合法的执行路径。改动前的问题_UFuncNoLoopError在改动之前对布尔数组调用np.positive会触发_UFuncNoLoopError。该异常定义在 numpy/_core/_exceptions.py继承自UFuncTypeError其错误信息形如ufunc positive did not contain a loop with signature matching types ...从源码结构看这个异常表示 ufunc 在解析输入 dtype 后找不到任何可匹配的内核循环。positive之前的类型描述中未包含布尔类型因此布尔数组无法匹配任何既有循环最终抛出该错误。_UFuncNoLoopError不仅在直接调用 ufunc 时会触发也被 C 层快速路径如 numpy/_core/src/multiarray/arrayfunction_override.c用于判断“无循环时延后到 Python 处理”。改动核心为布尔类型注册循环改动位于 ufunc 生成的类型描述表中numpy/_core/code_generators/generate_umath.py。positive的定义如下positive: Ufunc(1, 1, None, docstrings.get(numpy._core.umath.positive), PyUFunc_SimpleUniformOperationTypeResolver, TD(?, cfunc_aliasabsolute, dispatch[(loops_logical, ?)]), TD(ints flts timedeltaonly), TD(cmplx, fpos), TD(O, fPyNumber_Positive), no_float_errorsTrue, ),逐行解读这一类型描述TD(?, cfunc_aliasabsolute, dispatch[(loops_logical, ?)])这是本次新增的核心条目表示布尔类型?的循环。它通过cfunc_aliasabsolute复用absolute绝对值的 C 内核而absolute本身对布尔类型也走loops_logical逻辑循环——对布尔值取正与取绝对值语义一致恒等操作因此复用是安全的TD(ints flts timedeltaonly)整数、浮点与 timedelta 类型沿用既有统一循环TD(cmplx, fpos)复数类型使用pos内核TD(O, fPyNumber_Positive)对象类型委托给 Python 的PyNumber_Positive即调用对象的__pos__PyUFunc_SimpleUniformOperationTypeResolver该 ufunc 采用“简单统一操作”类型解析器即输入与输出 dtype 保持一致、逐元素应用同一操作。这意味着np.positive在布尔数组上等效于一个恒等复制操作x的结果与原数组逐元素相等仍是布尔 dtype同时支持out就地写入。官方文档语义一元 是 np.positive 的简写positive的官方文档位于 numpy/_core/code_generators/ufunc_docstrings.py其要点如下功能描述Numerical positive, element-wise即逐元素求数值正返回语义y x等价关系np.positive等价于x.copy()但仅对支持算术运算的类型有定义——这正是字符串、datetime64 等类型仍会报错的原因简写形式对 ndarray 使用一元运算符即为np.positive的简写例如x1等价于np.positive(x1)。因此本次改动同时作用于两种调用方式np.positive(arr)与arr二者底层共享同一个 ufunc 实现。测试验证行为契约对应的单元测试位于 numpy/_core/tests/test_umath.py 的TestPositive类它明确了改动后的行为契约class TestPositive: def test_valid(self): valid_dtypes [int, bool, float, complex, object] for dtype in valid_dtypes: x np.arange(5).astype(dtype) result np.positive(x) assert_array_equal(x, result, strictTrue, err_msgstr(dtype)) def test_invalid(self): with assert_raises(TypeError): np.positive(np.datetime64(2000-01-01)) with assert_raises(TypeError): np.positive(np.array([foo], dtypestr)) with assert_raises(TypeError): np.positive(np.array([bar], dtypeobject)) def test_bool(self): x np.array([True, False]) assert_array_equal(x, x, strictTrue) assert np.positive(x, outx) is x for scalar in (np.True_, True): result np.positive(scalar) assert type(result) is np.bool assert result scalar从测试可以归纳出以下契约可用类型int、bool、float、complex、object均可执行np.positive且结果与原数组严格相等strictTrue同时校验 dtype 与值不可用类型datetime64、str字符串 dtype 数组以及存放字符串的对象数组仍抛出TypeError说明改动仅扩展了布尔类型未改变其他类型的行为边界布尔专项x与np.positive(x)等价支持outx就地操作返回同一对象对 Python 布尔标量True与np.True_返回类型为np.bool保持标量语义一致。此外np.positive的out与where组合用法见 numpy/_core/tests/test_ufunc.py与半精度类型numpy/_core/tests/test_half.py、datetime 数组的负向测试numpy/_core/tests/test_datetime.py同样在既有测试集中得到覆盖。对用户代码的实际影响之前会报错 import numpy as np np.positive(np.array([True, False])) UFuncNoLoopError: ufunc positive did not contain a loop之后正常返回 import numpy as np np.positive(np.array([True, False])) array([ True, False]) np.array([True, False]) array([ True, False])实际影响包括对布尔数组使用一元的代码不再需要绕过写法例如改用x.copy()或np.abs(x)np.positive(x, outx)可用于布尔数组的就地复制场景返回原对象is判定为真由于positive对布尔类型等价于恒等操作其返回数组保持布尔 dtype不会发生 dtype 提升需要注意的是本次改动不改变字符串、datetime64 等非算术类型的报错行为np.positive(np.array([foo], dtypestr))依然抛出TypeError。版本说明与适用前提本条 change note 位于doc/release/upcoming_changes/目录该目录存放尚未发布版本的增量变更说明文件以关联 PR/issue 编号命名例如32100.improvement.rst因此该行为改进将随下一个 NumPy 次要/补丁版本发布。如果你当前使用的 NumPy 版本较早请以np.positive(np.array([True, False]))的实际运行结果为准升级到包含该改动的版本后即可直接使用。延伸阅读发布说明原文doc/release/upcoming_changes/32100.improvement.rstufunc 生成与类型描述numpy/_core/code_generators/generate_umath.pypositive官方文档numpy/_core/code_generators/ufunc_docstrings.py单元测试numpy/_core/tests/test_umath.py异常定义numpy/_core/_exceptions.py【免费下载链接】numpyThe fundamental package for scientific computing with Python.项目地址: https://gitcode.com/gh_mirrors/nu/numpy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考