Numba在nopython模式下不支持字符串.
2.6.2. Built-in types
2.6.2.1. int, bool […]
2.6.2.2. float, complex […]
2.6.2.3. tuple […]
2.6.2.4. list […]
2.6.2.5. set […]
2.6.2.7. bytes, bytearray, memoryview
The bytearray type and, on Python 3, the bytes type support indexing, iteration and retrieving the len().
[…]
因此根本不支持字符串,字节不支持相等性检查.
但是,您可以传入字节并迭代它们.这使得编写自己的比较函数成为可能:
import numba as nb
@nb.njit
def bytes_equal(a, b):
if len(a) != len(b):
return False
for char1, char2 in zip(a, b):
if char1 != char2:
return False
return True
不幸的是,下一个问题是numba不能“降低”字节,所以你不能直接硬编码函数中的字节.但是字节基本上只是整数,而bytes_equal函数适用于numba支持的所有类型,它们具有长度并且可以迭代.所以你可以简单地将它们存储为列表:
import numba as nb
@nb.njit
def foo(a, t):
if bytes_equal(t, [97, 119, 101, 115, 111, 109, 101]):
return a**2
elif bytes_equal(t, [100, 101, 102, 97, 117, 108, 116]):
return a**3
else:
return a
或者作为全局数组(感谢@chrisb – 请参阅注释):
import numba as nb
import numpy as np
AWESOME = np.frombuffer(b'awesome', dtype='uint8')
DEFAULT = np.frombuffer(b'default', dtype='uint8')
@nb.njit
def foo(a, t):
if bytes_equal(t, AWESOME):
return a**2
elif bytes_equal(t, DEFAULT):
return a**3
else:
return a
两者都能正常工作:
>>> foo(10, b'default')
1000
>>> foo(10, b'awesome')
100
>>> foo(10, b'awe')
10
但是,您不能将bytes数组指定为默认值,因此需要显式提供t变量.这样做也让人觉得很烦.
我的观点:只需执行if t == …检查正常函数并调用ifs中的专用numba函数.字符串比较在Python中非常快,只需将数学/数组密集型内容包装在numba函数中:
import numba as nb
@nb.njit
def awesome_func(a):
return a**2
@nb.njit
def default_func(a):
return a**3
@nb.njit
def other_func(a):
return a
def foo(a, t='default'):
if t == 'awesome':
return awesome_func(a)
elif t == 'default':
return default_func(a)
else:
return other_func(a)
但请确保您确实需要numba功能.有时普通的Python / NumPy足够快.只需简要介绍numba解决方案和Python / NumPy解决方案,看看numba是否能让它显着提高速度. 🙂