Python 谓词和条件

Python Predicates and Conditionals

github 上的一位用户使用 numba no python 模式报告了以下代码的错误:

from numba import njit
import numpy as np

@njit
def foo():
    a = np.ones(1, np.bool_)
    if a > 0:
        print('truebr')
    else:
        print('falsebr')

foo()

他被告知表达式 a > 0 不是谓词而是条件表达式。 为了修复它,他要 "Wrap conditionals in truth to create predicates".

这是否意味着 (a > 0) == True 会修复 numba 或其他方面出现的错误。

https://github.com/numba/numba/pull/3901/commits/598cdd1707fdeb11b8f1d70aef2d3e36ef37bd34。这是对 numba 中这些类型错误的修复吗?

在 Python(不是 numba)中,函数有效:

In [412]: def foo(): 
     ...:     a = np.ones(1, np.bool_) 
     ...:     if a > 0: 
     ...:         print('truebr') 
     ...:     else: 
     ...:         print('falsebr') 
     ...:                                                                                      
In [413]: foo()                                                                                
truebr

但是如果a是一个有更多值的数组:

In [414]: def foo(): 
     ...:     a = np.ones(2, np.bool_) 
     ...:     if a > 0: 
     ...:         print('truebr') 
     ...:     else: 
     ...:         print('falsebr') 
     ...:                                                                                      
In [415]: foo()                                                                                
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

如果我在 njit 中尝试你的函数,我会得到很长的回溯;显示或分析时间太长,但它基本上告诉我它不能在 njit 模式下完成。鉴于上述值错误,我并不感到惊讶。 njit 不允许 'just-one' 真值数组。

作为一般规则,当使用 numba 时,您应该迭代。这是它的主要目的 - 运行 numpy/python 问题,否则这些问题将因迭代而变得过于昂贵。不要指望 numba 来处理 Python.

的所有细微差别

如果我更改函数以测试 a 的每个元素,它会起作用:

In [421]: @numba.njit 
     ...: def foo(): 
     ...:     a = np.array([True]) 
     ...:     for i in a: 
     ...:         if i > 0: 
     ...:             print('truebr') 
     ...:         else: 
     ...:             print('falsebr') 
     ...:                                                                                      
In [422]: foo()                                                                                
truebr

all(或any)包装器也可以工作:

In [423]: @numba.njit 
     ...: def foo(): 
     ...:     a = np.array([True]) 
     ...:     if (a > 0).all(): 
     ...:         print('truebr') 
     ...:     else: 
     ...:         print('falsebr') 
     ...:                                                                                      
In [424]: foo()                                                                                
truebr