我有一个python字典,键是字符串,值是字符串列表
myDict = {'key1': ['value1', 'value2'],
'key2': ['value3', 'value4']}
我想在numba jit函数中使用这个字典。在第一步中,我尝试创建一个Numba类型的字典,并在基于web
的代码和文档的函数中使用它。from numba import njit
from numba.core import types
from numba.typed import Dict
d = Dict.empty(
key_type=types.unicode_type,
value_type=types.ListType(types.unicode_type),
)
# The typed-dict can be used from the interpreter.
d['key1'] = np.asarray(['value1', 'value2'], dtype='U')
d['key2'] = np.asarray(['value3', 'value4'], dtype='U')
但是这已经导致了一个奇妙的错误
No implementation of function Function(<built-in function setitem>) found for signature:
>>> setitem(DictType[unicode_type,ListType[unicode_type]]<iv=None>, unicode_type, array([unichr x 1], 1d, C))
手工重新创建字典也不是一种选择,因为字典非常大。所以我需要将python字典转移到numba字典
我尝试重用这里提供的解决方案:https://numba.discourse.group/t/how-to-convert-a-non-numba-dictionary-to-a-nb-typed-dict/865但这里再次-我没有提供正确的value_type从上面的玩具示例
我有一个python字典,键是字符串,值是字符串列表
请注意,Numba还几乎不支持字符串。有一个最小的支持,但你不能对字符串做任何真正有用的事情,字符串操作目前非常慢(以及编译时间)。
这已经导致了一个奇妙的错误
这是因为值类型是types.ListType(types.unicode_type)
,所以用np.asarray
设置值。类型化列表和数组是不同的不兼容类型。你应该从两者中选择一个。如果字符串的大小变化不大,我建议您使用Numpy数组。请注意,Numpy字符串内部存储在一种ND字符数组中,因此最大的字符串决定了数组的形状。字符串的限定长度是固定的,并且是类型的部分。同时,list of strings是一个引用字符串的列表。
如果你选择使用列表,那么你需要构建并填充一个类型化列表(这与CPython的通常反射列表不同/不兼容)。
如果选择Numpy array,则可以使用类型types.UnicodeCharSeq(16)[:]
,np.asarray
中使用dtype='U16'
。这里,16是最大字符数。必须指定它,因为它是类型的一部分。如果你不知道这个值,那么你当然需要使用可变大小字符串的列表。无限)。这个约束来自Numpy,但它通常不是什么大问题,因为边界是动态找到的。然而,Numba强制类型在编译时定义好,那么它不能动态更改,应该在赋值之前预定义。
手动重新创建字典也不是一种选择,因为字典非常大。所以我需要将python字典转移到numba字典。
简而言之,这是不可能的。基本的纯python字典和列表称为反射字典和反射列表。反射列表以前是支持的,但现在已经弃用了,所以使用它不是一个好主意。Numba转向类型化字典和类型化列表,因为反射列表会引起很多问题。实际上,Numba需要静态类型的项,以便更快。对引用计数的纯python gil保护对象进行操作会阻止任何可能的优化,也不会在并行上下文中使用该对象,从而导致代码像CPython一样慢。纯python字典/列表本质上是低效的。类型化集合以牺牲强制复制为代价解决了这个问题。
另一种解决方案是在对象模式上下文中提取字典项,但这是低效的,并且提取的对象需要键入以便在njit上下文中使用。更不用说从两种模式切换是实验性的(对于像这种不重要的情况,还相当不稳定)。