1

enter image description here

I have a numpy array and corresponding lookup values. From every column of data, I should get maximum position of the corresponding lookup an convert that position into result of data.

I have to do as shown in the picture.

Picture speaks better than my language.

import numpy as np

data = np.array([[0, 2, 1, 4, 3, 2, 4, 4, 1],
                 [1, 1, 2, 0, 3, 4, 4, 2, 1],
                 [2, 2, 1, 4, 4, 1, 4, 4, 4]] )

print (data)

print ()

lookup = np.array([[60, 90, 90, 60, 50],
                  [90, 90, 80, 90, 90],
                  [60, 40, 90, 60, 50]])

print (lookup)

print ()

I did as follows:

data = data.transpose(1,0)

lookup = lookup.transpose(1,0)

results = []       
for d in data:   
   matches = lookup[d].diagonal()
   print (matches)
   idx = np.argmax(matches, axis=0)
   res = d[idx]
   results.append(res)

print ()

print (results)  

It worked. But, any better way of doing it?

2
  • Can you describe what you are trying to do, in words not in pictures. Commented Jan 13, 2020 at 17:37
  • Added in the question. Commented Jan 13, 2020 at 17:41

3 Answers 3

1

You can use flattening fact:

l = lookup.shape[1]
data1 = (data + [[0],[l], [2*l]]).copy()
matches = lookup.flatten()[data1.flatten()].reshape(data1.shape).T
results = data.T[:, np.argmax(matches, axis = 1)].diagonal()
print(matches)
print(results)

Output

[[60 90 90]
 [90 90 90]
 [90 80 40]
 [50 90 50]
 [60 90 50]
 [90 90 40]
 [50 90 50]
 [50 80 50]
 [90 90 50]]  # matches

[1 2 1 0 3 2 4 2 1]  #results
Sign up to request clarification or add additional context in comments.

3 Comments

you got matches. then, how to get results?
[1, 2, 1, 0, 3, 2, 4, 2, 1]
getting argmax of the matches you produced and convert into data values. expected result is [1, 2, 1, 0, 3, 2, 4, 2, 1]
0

I'm not sure I understand you, but maybe this is what you're looking for?

data = data.T
lookup = lookup.T
cols = np.zeros_like(data) + np.array([0, 1, 2])
idx = np.argmax(lookup[data, cols], axis=1)
data[np.arange(data.shape[0]), idx]

3 Comments

why + np.array([0, 1, 2])?
just a lazy way to make something like [[0, 1, 2], [0, 1, 2], [0, 1, 2],...]] i.e. the colums for each row. Maybe a better route would be to use np.ndgrid.
lookup[data, cols] is your matches
0

Use numpy's fancy indexing. With it, you can provide arrays of indexes. See example:

data = np.arange(20)
data[[0, 1, 5, 10]]    # array([ 0,  1,  5, 10])

The arrays used for the indexing also broadcast. See example:

data = np.arange(20).reshape(5, 4)
i = np.array([0, 4])
j = np.array([0, 3])
data[i, j]                                 # array([ 0, 19])
i, j = i[:, np.newaxis], j[np.newaxis, :]
data[i, j]                                 # array([[ 0,  3], [16, 19]])

In your case, matches is such that matches[i, j] = lookup[i, data[i, j]]. Using fancy indexing, we do:

i = np.arange(data.shape[-2])[:, np.newaxis]
matches = lookup[i, data]

And the final result is supposed to be result[j] = data[i_max[j], j], with i_max[j] = argmax_i(matches[i, j]), which translates to:

i_max = np.argmax(matches, axis=-2)
j = np.arange(data.shape[-1])
result = data[i_max, j]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.