2016-02-06 55 views
2

我嘗試使用numba函數,需要在(int,int)元組作爲關鍵字的非常大的(10e6)字典上進行搜索。numba @njit更新大字典

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 

的簡化版本看起來像這樣

# @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 } 

這樣看來,@njit不接受字典的功能ARG?

我想知道如何重寫這個,特別是if (i, j) in dict_with_tuples_key做搜索的部分。

回答

3

njit意味着該功能在nopython模式編譯。 A dictlisttuple是python對象,因此不受支持。不作爲參數,不在函數內部。

如果你的字典鍵都不同,我會考慮使用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) 

既然你已經收錄你的字典,元組的過渡問題索引數組不會很大。

+0

我剛剛用您的解決方案 – user3313834

+0

@ user3313834影響我的問題 - 請不要做這樣的後續問題。如果我回答了原來的問題:好的,然後upvote /接受/忽略我的答案。如果答案沒有解決你的問題:等待解決它的另一個答案。但在我看來,像你有一個關於如何在numba中創建開放網格的新問題,這與原始問題有些不相干。那麼請打開另一個問題,不要更新這個問題。 – MSeifert

+0

對不起,現在是在一個專門的問題http://stackoverflow.com/q/35340440/3313834 – user3313834

0

作爲替代你可以試試,如果這不夠快:

from collections import Counter 


c2 = Counter(dict_with_tuples_key) 
c1 = Counter(tuple(x) for x in myarray) 
new_dict = dict(c1 + c2)