【问题标题】:Numba - string typesNumba - 字符串类型
【发布时间】:2020-11-12 15:53:19
【问题描述】:

我认为这是一个简单的问题,但我发现 numba 文档缺少关于如何将字符串类型与 numpy 数组和字典一起使用的内容。我有一个我想使用 numba 的函数,它需要一个邮政编码列表,然后是一个映射邮政编码 -> 值的字典。我知道我可以将 zip 转换为 int 数据类型,但我希望能够使用其他无法强制转换为 int 类型的值来执行此操作。

from numba.typed import Dict
from numba.core import types
@jit(nopython=True)
def zip_func(zip_array,zip_dict):
    return zip_dict[zip_array[0]]
#This would be a longer array using real data
myzips = np.array(['12345'],dtype='<U5')
mydict = {"12345":5}
numba_dict = Dict.empty(key_type=types.unicode_type,value_type=types.int64)
for key,value in mydict.items():
    numba_dict[key] = value
zip_func(myzips,numba_dict)

这会产生以下错误,如果我理解正确,当键键入为 types.unicode_type 时,它​​基本上无法使用长度为 5 的固定长度字符串作为键。如何对齐这些类型?

---------------------------------------------------------------------------
TypingError                               Traceback (most recent call last)
<ipython-input-4-93b4a32d59d4> in <module>
     12 for key,value in mydict.items():
     13     numba_dict[key] = value
---> 14 zip_func(myzips,numba_dict)

/sas/python/app/miniconda3/envs/py3lu/lib/python3.6/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
    399                 e.patch_message(msg)
    400 
--> 401             error_rewrite(e, 'typing')
    402         except errors.UnsupportedError as e:
    403             # Something unsupported is present in the user code, add help info

/sas/python/app/miniconda3/envs/py3lu/lib/python3.6/site-packages/numba/core/dispatcher.py in error_rewrite(e, issue_type)
    342                 raise e
    343             else:
--> 344                 reraise(type(e), e, None)
    345 
    346         argtypes = []

/sas/python/app/miniconda3/envs/py3lu/lib/python3.6/site-packages/numba/core/utils.py in reraise(tp, value, tb)
     78         value = tp()
     79     if value.__traceback__ is not tb:
---> 80         raise value.with_traceback(tb)
     81     raise value
     82 

TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Internal error at <numba.core.typeinfer.IntrinsicCallConstraint object at 0x7ff4562e2518>.
Failed in nopython mode pipeline (step: nopython mode backend)
Cannot cast [unichr x 5] to unicode_type: %".21" = load [5 x i32], [5 x i32]* %"key"

File "../../../python/app/miniconda3/envs/py3lu/lib/python3.6/site-packages/numba/typed/dictobject.py", line 730:
    def impl(d, key):
        castedkey = _cast(key, keyty)
        ^

[1] During: lowering "$0.4 = call $0.1(key, $0.3, func=$0.1, args=[Var(key, dictobject.py:730), Var($0.3, dictobject.py:730)], kws=(), vararg=None)" at /sas/python/app/miniconda3/envs/py3lu/lib/python3.6/site-packages/numba/typed/dictobject.py (730)
[2] During: typing of intrinsic-call at <ipython-input-4-93b4a32d59d4> (7)
Enable logging at debug level for details.

File "<ipython-input-4-93b4a32d59d4>", line 7:
def zip_func(zip_array,zip_dict):
    return zip_dict[zip_array[0]]

【问题讨论】:

  • zip_array[0]zip_array.item() 返回不同的类型。 item 可能有效。我没用过numba's Dict
  • 是的,问题是字典有 types.unicode_type 而数组是类型

标签: python numpy types numba


【解决方案1】:

您可以从 unichar dtype 创建自定义 Numba 类型,而不是使用 numba.types.unicode_type 作为字典的 key_type

np_unichar = numpy.dtype('<U5')
UnicharType = numba.from_dtype(np_unichar)

现在,您可以使用 UnicharType 告诉 Numba 您需要 [unichr x 5] 类型的值。

另外,我发现简单地将空字符串添加到 [unichr x N] 将强制进行类型转换。这意味着,zip_array[0] + '' 将被处理为 numba.types.unicode_type

【讨论】:

  • 解决了我的问题。请注意,此代码必须在 jit 函数之外
  • 是的。您必须从 python 解释器的上下文中创建 numba 类型签名。很高兴我的回答很有帮助。
【解决方案2】:

对于未来的读者,请注意numba.types.UnicodeCharSeq(5) 可以直接在签名中使用。对于基于字符串的签名,可以使用“UnicodeCharSeq(5)”。这是一个基本的例子:

# Take a contiguous Numpy array of [unichar x 5] strings, aka 'U5'
@numba.njit('int64(UnicodeCharSeq(5)[::1])')
def compute(arr):
    return len(arr)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-21
    • 2019-11-21
    • 2021-03-04
    • 2013-10-15
    • 2013-05-30
    • 2019-02-27
    • 2020-01-07
    相关资源
    最近更新 更多