Question

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:

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

Array 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:

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
Was it helpful?

Solution

vectorize it.

@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). As you already found out, the tricky part, which vectorize takes care of for you, is maintaining the shape.

This provides simplicity, but not necessarily speed, because vectorize is implemented using python-space loops.

OTHER TIPS

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().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top