Reputation: 141
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?
Upvotes: 1
Views: 114
Reputation: 189
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]
Upvotes: 0
Reputation: 3988
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
Upvotes: 1
Reputation: 45741
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]
Upvotes: 0