Replace values in a dimension of a 2D numpy array, from a map dictionary

Question:

I need to replace the values of a certain index in all lists inside a list, with a value from a dictionary, which is mapped for a different index of that list.
Or, if the first index value of every list(which are inside a bigger list), equals a key in the dictionary, then the value at the second index in that list, changes to the value from the dict.

For ex: L = [[1,2,3],[4,5,6],[7,8,9]]
        D = {'1':50, '4':10, '7':20} ##if first index is any of these keys, then the second index becomes the value
        New List = [[1,50,3],[4,10,6],[7,20,9]]

This is because I have a image with HSV values, and need to replace the saturation value of every pixel according to a curve, which describes the saturation for each color(hue), like the Hue vs Saturation curve in after effects.

So a curve describes the saturation values for each hue value, I need to iterate all the pixels, and according to their hue values, change the saturation from a dictionary, hope this explains well.

Asked By: rummy rummyrum

||

Answers:

Use

for sub in L:
    sub[1] = D.get(str(sub[0]), 0)

This uses a default value of 0 if the dictionary does not have the List value.

Produces

[[1, 50, 3], [4, 10, 6], [7, 20, 9]]
Answered By: user19077881

Yes this can be done as follows:

L = np.array([[1,2,3],[6,4,5],[7,8,9], [10,11,12]])
D = {'1':50, '4':10, '7':20, '8':30, '10':45}
keys = np.array(list(D.keys()), dtype=int)
vals = np.array(list(D.values()), dtype=int)

srt = L.ravel().argsort()

ind = np.searchsorted(L.ravel(),keys, sorter=srt)


r =L.ravel()
r[srt[ind]+1]= vals
print(r.reshape(L.shape))

Output:

 [[1 50  3]
 [ 6  4 10]
 [ 7 20 30]
 [10 45 12]]
Answered By: MSS

If the numbers are all natural numbers and the range is not very large, it may be the fastest to make a mapping array and generate the results through the index:

>>> L
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> mapping = np.zeros(L[:, 0].max() + 1, int)
>>> mapping[np.fromiter(D, int)] = list(D.values())
>>> mapping
array([ 0, 50,  0,  0, 10,  0,  0, 20])
>>> L[:, 1] = mapping[L[:, 0]]
>>> L
array([[ 1, 50,  3],
       [ 4, 10,  6],
       [ 7, 20,  9]])
Answered By: Mechanic Pig