简体   繁体   English

遍历两个数组以查找字典中的值

[英]Iterate over two arrays looking up values in a dict

So I have a dictionary: 所以我有一本字典:

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, 

I also have two arrays that combined give the tuple key for my dictionary above: 我还有两个数组组合在一起,为上面的字典提供了元组键:

Array 1: 阵列1:

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

Array 2: 阵列2:

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

My code is: 我的代码是:

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

This code doesn't work. 此代码无效。 What I want to get is an array that looks like this: 我想要得到的是一个看起来像这样的数组:

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

So essentially I have two arrays containing the values to use as the key for my lookup dict and I am not sure how to implement this in code. 因此,从本质上讲,我有两个包含值的数组,这些值用作我的查询字典的键,而且我不确定如何在代码中实现这一点。

Any suggestions or help would be greatly appreciated. 任何建议或帮助将不胜感激。

Thanks, 谢谢,

Nick 缺口

Solution using vectorise: 使用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

vectorize it. 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]])

In general, using vectorize is an easy way to extend scalar-operations (in your case, getting a value from a dict by a scalar key) to work on arrays (in your case, two arrays of keys). 通常,使用vectorize是扩展标量运算(在您的情况下,通过标量键从字典获取值)以在数组(在您的情况下为两个键数组)上工作的简便方法。 As you already found out, the tricky part, which vectorize takes care of for you, is maintaining the shape. 正如您已经发现的那样, vectorize处理的棘手部分是保持形状。

This provides simplicity, but not necessarily speed, because vectorize is implemented using python-space loops. 这提供了简单性,但不一定提供速度,因为vectorize是使用python-space循环实现的。

Try this: 尝试这个:

>>> 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]]
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))]

Output: 输出:

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

You can convert this to a list of lists as desired, and even make it a np.array() . 您可以根据需要将其转换为列表列表,甚至可以将其设置为np.array()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM