2014-05-01 57 views
2

所以我有一本字典:遍历两个数组在一个字典查找值

LCM_SCS = { 
     (1, "A"): 36, (1, "B"): 60, (1, "C"): 73, (1, "D"): 79, 
     (2, "A"): 36, (2, "B"): 60, (2, "C"): 73, (2, "D"): 79, 
     (3, "A"): 74, (3, "B"): 83, (3, "C"): 88, (3, "D"): 90, 
     (4, "A"): 68, (4, "B"): 79, (4, "C"): 86, (4, "D"): 89, 
     (5, "A"): 30, (5, "B"): 58, (5, "C"): 71, (5, "D"): 78, 
     (6, "A"): 39, (6, "B"): 61, (6, "C"): 74, (6, "D"): 80, 
     (7, "A"): 39, (7, "B"): 61, (7, "C"): 74, (7, "D"): 80, 
     (8, "A"): 39, (8, "B"): 61, (8, "C"): 74, (8, "D"): 80, 
     (10, "A"): 30, (10, "B"): 48, (10, "C"): 65, (10, "D"): 73, 

我也有两个数组,联合给元组键我的字典上面:

阵列1:

array1 = np.array([[1, 1, 1], 
      [2, 2, 3], 
      [2, 4, 5]]) 

阵列2:

array2 = np.array([["A", "A", "A"], 
      ["B", "B", "B"], 
      ["C", "C", "C"]]) 

我的代码是:

Numbers = np.empty_like(array1) 


for [x, y], (value1, value2) in np.ndenumerate(izip(array1, array2)): 
     CN_numbers[x, y] = LCM_SCS.get((value1, value2)) 

    return Numbers 

此代码无效。我希望得到的是一个数组,看起来像这样:

Numbers = array([[36, 36, 36], 
      [60, 60, 83], 
      [73, 86, 71]]) 

所以基本上我有一个包含的值作为我查找字典的关键是使用两个数组,我不知道如何在代码中实现这一点。

任何建议或帮助将不胜感激。

感谢,

尼克

解决方案使用vectorise:

a_new = np.empty_like(array1) 

def get_CN_numbers(a1, a2): 
    return LCM_SCS[(a1, a2)] # your basic scalar-operation 

V_get_CN = np.vectorize(get_CN_numbers) 

a_new = V_get_CN(array1, array2) 

print a_new 
+0

检查我的编辑:) –

回答

3

vectorize它。

@numpy.vectorize 
def get_CN_numbers(a1, a2): 
    return LCM_SCS[(a1,a2)] # your basic scalar-operation 

get_CN_numbers(array1, array2) 
=> 
array([[36, 36, 36], 
     [60, 60, 83], 
     [73, 86, 71]]) 

一般而言,使用vectorize是扩展标量操作(在你的情况下,通过一个标量键正从一个字典值)到阵列的工作(在你的情况下,密钥的两个数组的简单方法)。正如你已经发现的那样,棘手的部分,vectorize照顾你,保持形状。

这提供了简单性,但不一定是速度,因为vectorize是使用python-space循环实现的。

+2

总是学习新的东西! – xbb

+0

嗨,这听起来似乎是一个非常简单的解决方案,但我似乎无法得到它的工作。我得到的错误:“TypeError:unhashable类型:'numpy.ndarray'” –

+0

忽略我犯了一个愚蠢的错误。 –

0
LCM_SCS = { 
     (1, "A"): 36, (1, "B"): 60, (1, "C"): 73, (1, "D"): 79, 
     (2, "A"): 36, (2, "B"): 60, (2, "C"): 73, (2, "D"): 79, 
     (3, "A"): 74, (3, "B"): 83, (3, "C"): 88, (3, "D"): 90, 
     (4, "A"): 68, (4, "B"): 79, (4, "C"): 86, (4, "D"): 89, 
     (5, "A"): 30, (5, "B"): 58, (5, "C"): 71, (5, "D"): 78, 
     (6, "A"): 39, (6, "B"): 61, (6, "C"): 74, (6, "D"): 80, 
     (7, "A"): 39, (7, "B"): 61, (7, "C"): 74, (7, "D"): 80, 
     (8, "A"): 39, (8, "B"): 61, (8, "C"): 74, (8, "D"): 80, 
     (10, "A"): 30, (10, "B"): 48, (10, "C"): 65, (10, "D"): 73} 

array1 = np.array([[1, 1, 1], [2, 2, 3], [2, 4, 5]]).tolist() 
array2 = np.array([["A", "A", "A"], ["B", "B", "B"], ["C", "C", "C"]]).tolist() 

array1 = [y for sub in array1 for y in sub] 
array2 = [y for sub in array2 for y in sub] 
results = [LCM_SCS[(array1[k], array2[k])] for k in range(len(array1))] 

输出:

[36, 36, 36, 60, 60, 83, 73, 86, 71] 

你可以根据需要将其转换为列表清单,甚至可以将其作为np.array()

+0

谢谢,但你的结果产生的输出不是我正在寻找。我想用字典中的新值维护数组的形状。 –

+0

@NickJones检查我的编辑:) –

2

试试这个:

>>> new_array = np.rec.fromarrays((array1,array2),names='x,y')  # This will generate all keys that you'll look value for. 
>>> print new_array 
[[(1, 'A') (1, 'A') (1, 'A')] 
[(2, 'B') (2, 'B') (3, 'B')] 
[(2, 'C') (4, 'C') (5, 'C')]] 
>>> result = np.zeros([3,3],dtype=int)  #Having issue to modify directly on new_array so I initialized a new numpy array to store result 
>>> for (x,y), value in np.ndenumerate(new_array): 
    result[x][y] = LCM_SCS[tuple(value)] 

>>> print result 
[[36 36 36] 
[60 60 83] 
[73 86 71]]