【问题标题】:How should I use an array (or tuple) as key and values for a Numba typed dictionary?我应该如何使用数组(或元组)作为 Numba 类型字典的键和值?
【发布时间】:2019-08-15 18:20:13
【问题描述】:

我有以下代码尝试将键值对存储到 numba 字典中。 Numba 的官方页面说新的类型化字典支持数组作为键,但我无法让它工作。 错误消息说密钥不能是散列。 知道如何让它工作吗?

In [7]: from numba.typed import Dict 
   ...: from numba import types 
   ...: import numpy as np        

In [15]: dd = Dict.empty(key_type=types.int32[::1], value_type=types.int32[::1],)                                                                                                                                  

In [16]: key = np.asarray([1,2,3], dtype=np.int32)                                                                                                                                                                 

In [17]: dd[key] = key   

错误信息:

TypingError:在 nopython 模式管道中失败(步骤:nopython 前端) array(int32, 1d, C) 类型的未知属性“hash

编辑: 我可能错过了一些东西。我可以在解释器中使用 types.UniTuple(没有 @jit 装饰器)。但是,当我将以下函数放入脚本 a.py 并使用命令“python a.py”运行它时,出现 UniTuple not found 错误。

@jit(nopython=True)
def go_fast2(date, starttime, id, tt, result): # Function is compiled and runs in machine code
    prev_record = Dict.empty(key_type=types.UniTuple(types.int64, 2),  value_type=types.UniTuple(types.int64, 3),)
    for i in range(1, length):
        key = np.asarray([date[i], id[i]], dtype=np.int64)
        thistt = tt[i]
        thistime = starttime[i]
        if key in prev_record:
            prev_time = prev_record[key][0]
            prev_tt = prev_record[key][1]
            prev_res = prev_record[key][2]
            if thistt == prev_tt and thistime - prev_time <= 30 * 1000 * 1000: # with in a 10 seconds window
                result[i] = prev_res + 1
            else:
                result[i] = 0
            prev_record[key] = np.asarray((thistime, thistt, result[i]), dtype=np.int64)
        else:
            result[i] = 0
            prev_record[key] = np.asarray((thistime, thistt, result[i]), dtype=np.int64)
    return 

【问题讨论】:

    标签: numba


    【解决方案1】:

    当前的文档说:

    可接受的键/值类型包括但不限于:unicode 字符串、数组、标量、元组。

    措辞确实使您看起来可能能够将数组用作键类型,但这是不正确的,因为数组不可散列,因为它是可变的。它也不适用于标准的python dict。您可以将数组转换为元组,这样就可以了:

    dd = Dict.empty(
        key_type=types.UniTuple(types.int64, 3), 
        value_type=types.int64[::1],)
    key = np.asarray([1,2,3], dtype=np.int64)
    dd[tuple(key)] = key
    

    请注意,您之前使用的 int32 dtype 不适用于 64 位机器,因为在数组上调用 tuple() 时,int32s 的元组将自动转换为 int64。

    另一个问题是元组具有固定大小,因此您不能使用任意大小的数组作为键。

    【讨论】:

    • 我收到以下错误...numba.errors.TypingError:在 nopython 模式管道中失败(步骤:nopython 前端)Module 类型的未知属性“UniTuple”()
    • 您使用的是哪个版本的 numba?我正在使用 0.45.1
    • 这里也一样。也在 0.45.1
    • 这很奇怪,因为如果您查看github.com/numba/numba/blob/master/numba/types/__init__.py,您会发现from .containers import * 应该包含UniTuple 类。另外,我提交了一个 PR 来澄清文档 github.com/numba/numba/pull/4455
    • 作为一种解决方法,我使用 njit 函数 foo(x, y, t = UniTuple(int64, 3)) 的可选属性在 Numba 之外创建类型,然后在 numba 内使用 t功能。
    猜你喜欢
    • 2013-01-19
    • 2010-10-31
    • 2020-09-25
    • 2019-10-25
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    相关资源
    最近更新 更多