Отключить отражение списка в Numba - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь ускорить мой код с помощью Numba.Одним из аргументов, которые я передаю в функцию, является изменяемый список списков.Когда я пытаюсь изменить один из подсписков, я получаю эту ошибку:

Ошибка в конвейере режима nopython (шаг: бэкэнд режима nopython) не может отразить элемент отраженного контейнера: отраженный список (отраженный список (int64))

На самом деле меня не волнует отражение изменений, которые я делаю в собственном списке в исходном списке Python.Как мне сказать Нумбе не отражать изменения?Документация довольно размыта в отношении отображения списка в Numba.

Спасибо,

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Если вы передаете список параметров списка в 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())
0 голосов
/ 15 ноября 2018

Цитирование непосредственно из документов:

В режиме nopython Numba не работает с объектами Python. список составлен во внутреннем представлении. Любые аргументы списка должны быть преобразуется в это представление по пути в режим Nopython и содержащиеся в них элементы должны быть восстановлены в исходном Python объекты через процесс, называемый отражением.

Отражение требуется для сохранения той же семантики, что и в обычный код Python. Однако процесс отражения может быть дорогим для больших списков и не поддерживается для списков, которые содержат отраженные типы данных. Пользователи не могут использовать список-список в качестве аргумента из-за этого ограничения.

Лучше всего было бы дать двумерный массив формы len(ll) x max(len(x) for x in 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

НТН.

...