关闭Numba中的列表反射功能

时间:2018-11-15 07:04:50

标签: python numba

我正在尝试使用Numba加速我的代码。我要传递给函数的参数之一是列表的可变列表。当我尝试更改子列表之一时,出现此错误:

  

在nopython模式管道中失败(步骤:nopython模式后端)   无法反映反射容器的元素:反射列表(reflected list(int64))

我实际上并不关心将对本地列表所做的更改反映到原始Python列表中。如何告诉Numba不要反映更改?关于Numba中的列表反映,该文档含糊不清。

谢谢

2 个答案:

答案 0 :(得分:1)

直接从文档中报价:

  

在nopython模式下,Numba不会对Python对象进行操作。清单是   编译成内部表示形式。任何列表参数必须是   在进入nopython模式的过程中转换为该表示形式,并且   它们包含的元素必须在原始Python中恢复   物体通过反射过程。

     

需要反射以保持与在   常规Python代码。但是,反射过程可能很昂贵   适用于大型列表,而包含以下列表的列表则不支持   反映的数据类型。 用户不能使用列表列表作为参数   由于此限制。

您最好的选择是给出形状为len(ll) x max(len(x) for x in ll)的2D numpy数组,其中ll为列表列表。我自己使用类似的方法来实现此目的,然后将arr, lengths传递给njit编译函数:

def make_2D_array(lis):
    """Funciton to get 2D array from a list of lists
    """
    n = len(lis)
    lengths = np.array([len(x) for x in lis])
    max_len = max(lengths)
    arr = np.zeros((n, max_len))

    for i in range(n):
        arr[i, :lengths[i]] = lis[i]
    return arr, lengths

HTH。

答案 1 :(得分:0)

如果将list参数的列表传递给numba,则应使用numpy数组而不是原始的Python列表。 Numba由于不支持列表功能而引发反射错误。您可以比较以下两个示例:

这出现了相同的错误:

TypeError: Failed in nopython mode pipeline (step: nopython mode backend)
cannot reflect element of reflected container: reflected list(reflected list(int64))

import numba

list_of_list = [[1, 2], [34, 100]]


@numba.njit()
def test(list_of_list):
    if 1 in list_of_list[0]:
        return 'haha'

test(list_of_list)

运行流畅的版本是

from numba import njit
import numpy as np


@njit
def test():
    if 1 in set(np_list_of_list[0]):
        return 'haha'


if __name__ == '__main__':
    list_of_list = [[1, 2], [34, 100]]
    np_list_of_list = np.array(list_of_list)
    print(test())