Предикаты Python и условные выражения

Пользователь на 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 не является предикатом, а скорее условным. Чтобы исправить это, он должен был «обернуть условные слова в правду, чтобы создать предикаты».

Означает ли это, что (a > 0) == True исправит ошибку, которая возникает в numba или что-то еще.

https://github.com/numba/numba/pull/3901/commits/598cdd1707fdeb11b8f1d70aef2d3e36ef37bd34 . Это исправление для этих типов ошибок в Numba?

Всего 1 ответ


В 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 Truth.

Как правило, при использовании numba вы должны выполнять итерацию. Это его основная цель - запускать проблемы numpy/python , которые в противном случае были бы слишком дорогими для повторения. Не рассчитывайте, что numba справится со всеми нюансами Python.

Если я изменю функцию для проверки каждого элемента, она будет работать:

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

Вся (или any ) оболочка также работает:

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