Numba即使有签名也无法确定空白清单的指纹

时间:2019-10-04 17:24:41

标签: python-3.x numba

我正在使用@jit签名来定义传入参数的类型。但是在调用函数时,我得到了:

ValueError: cannot compute fingerprint of empty list

我知道列表为空,但是我的签名定义了该列表,因此不确定Numba为什么不使用该签名。

我尝试了不同形式的签名(字符串形式和元组形式),但仍然给出错误。从文档中我还不清楚,为什么这些签名没有定义传入的参数,而仍然依赖于推断类型。

@nb.jit("void(List(int64), int64, List(List(int64)))", nopython=True, cache=True)
def _set_indices(keys_as_int, n_keys, indices):
    for i, k in enumerate(keys_as_int):
        indices[k].append(i)
    indices = [([np.array(elt) for elt in indices])]

def group_by(keys):
    _, first_occurrences, keys_as_int = np.unique(keys, return_index=True, return_inverse=True)
    n_keys = max(keys_as_int) + 1
    indices = [[] for _ in range(max(keys_as_int) + 1)]
    print(str(keys_as_int) + str(n_keys) + str(indices))
    _set_indices(keys_as_int, n_keys, indices)
    return indices

result = group_by(['aaa', 'aab', 'aac', 'aaa', 'aac'])
print(str(result))

我希望签名可以对传入的参数强制执行数据键入,而无需推断数据类型。 实际错误

<ipython-input-274-401e07cd4e63> in <module>
----> 1 result = group_by(['aaa', 'aab', 'aac', 'aaa', 'aac'])
      2 print(str(result))

<ipython-input-273-acdebb81069c> in group_by(keys)
      4     indices = [[] for _ in range(max(keys_as_int) + 1)]
      5     print(str(keys_as_int) + str(n_keys) + str(indices))
----> 6     _set_indices(keys_as_int, n_keys, indices)
      7     return indices

ValueError: cannot compute fingerprint of empty list

1 个答案:

答案 0 :(得分:1)

因此,我找到了一种解决方法,以使您的代码正常工作。这是一个github issue,问题与您面临的问题几乎相同。因此,我尝试创建一个带有虚拟值-1的列表,该列表将在结尾处删除。但是,我遇到了“反射列表例外”。您可以详细了解here。因此,我不得不使用Numba的类型列表。您可以查看有关此data type here的更多信息。长话短说,这是可以在No Python模式下工作的最终代码,并且可以按预期返回正确的结果。

import numba as nb
import numpy as np
from numba.typed import List

@nb.jit(nopython=True, cache=True)
def _set_indices(keys_as_int, n_keys, indices):
    # Do some operation
    for i, k in enumerate(keys_as_int):
        indices[k].append(i)

    # Drop the dummy element in the final result
    indices = [elem[1:] for elem in indices]

    # Return the final indices
    return indices

def group_by(keys):
    _, first_occurrences, keys_as_int = np.unique(keys, return_index=True,
                                                  return_inverse=True)
    n_keys = max(keys_as_int) + 1

    # Simply adding the dummy element doesn't work here
    # Error: cannot reflect element of reflected container: reflected list(reflected list(int64))
    # indices = [[-1] for _ in range(max(keys_as_int) + 1)]
    # A workaround is to create Numba's version of typed-list
    indices = List()
    for i in range(max(keys_as_int) + 1):
        l = List()
        l.append(-1)
        indices.append(l)

    print(str(keys_as_int), str(n_keys),  str(indices))
    indices = _set_indices(keys_as_int, n_keys, indices)
    return indices

result = group_by(['aaa', 'aab', 'aac', 'aaa', 'aac'])

# Conversion of Numba's typed list inside NoPython mode returns error
# Hence do it outside the function
result = [np.asarray(elem) for elem in result]
print(result)

这里是link to Google colab notebook,上面有工作代码。如果要挖掘反射列表异常​​,请转到最后一个单元格。