numba @njit更新一个大字典

use*_*834 3 python jit numba

我尝试使用numba作为一个函数,需要在一个非常大的(10e6)dict上搜索(int,int)元组作为键.

import numpy as np
from numba import njit

myarray = np.array([[0, 0],  # 0, 1
                    [0, 1],
                    [1, 1],  # 1, 2
                    [1, 2],  # 1, 3
                    [2, 2],
                    [1, 3]]
) # a lot of this with shape~(10e6, 2)

dict_with_tuples_key = {(0, 1): 1,
                        (3, 7): 1} # ~10e6 keys 
Run Code Online (Sandbox Code Playgroud)

简化版本看起来像这样

# @njit
def update_dict(dict_with_tuples_key, myarray):
    for line in myarray:
        i, j = line
        if (i, j) in dict_with_tuples_key:
            dict_with_tuples_key[(i, j)] += 1
        else:
            dict_with_tuples_key[(i, j)] = 1
    return dict_with_tuples_key

new_dict = update_dict(dict_with_tuples_key, myarray)
print new_dict

new_dict = update_dict2(dict_with_tuples_key, myarray)
# print new_dict
# {(0, 1): 2,   # +1 already in dict_with_tuples_key
#  (0, 0): 1,   # diag
#  (1, 1): 1,   # diag
#  (2, 2): 1,   # diag
#  (1, 2): 1,   # new from myarray
#  (1, 3): 1,   # new from myarray
#  (3, 7): 1 }
Run Code Online (Sandbox Code Playgroud)

似乎@njit不接受dict作为函数arg?

我想知道如何重写这个,特别if (i, j) in dict_with_tuples_key是搜索的部分.

MSe*_*ert 5

njit表示该函数是在nopython模式下编译的.一dict,listtuple是Python对象,因此不支持.不作为参数而不是函数内部.

如果你的dict键都不同,我会考虑使用2D numpy数组,其中第一个轴代表dict-key-tuple的第一个索引,第二个轴代表第二个索引.然后你可以把它重写为:

from numba import njit
import numpy as np

@njit
def update_array(array, myarray):
    elements = myarray.shape[0]
    for i in range(elements):
        array[myarray[i][0]][myarray[i][1]] += 1 
    return array


myarray = np.array([[0, 0], [0, 1], [1, 1],
                    [1, 2], [2, 2], [1, 3]])

# Calculate the size of the numpy array that replaces the dict:
lens = np.max(myarray, axis=0) # Maximum values
array = np.zeros((lens[0]+1, lens[1]+1)) # Create an empty array to hold all indexes in myarray
update_array(array, myarray)
Run Code Online (Sandbox Code Playgroud)

由于您已经使用元组索引了字典,因此索引数组的转换问题将不会很好.

  • @ user3313834 - 请不要做这样的后续问题。如果我回答了最初的问题:很好,那么赞成/接受/忽略我的回答。如果答案不能解决您的问题:等待另一个解决问题的答案。但在我看来,您有一个关于如何在 numba 中创建开放网格的新问题,这与原始问题有些无关。那么请打开另一个问题,不要更新这个问题。 (2认同)