Numpy argmin() to find the nearest tuple

54 views Asked by At

I have an array of tuples, I need to find the tuple from that array that is the closes to a given tuple(element wise), that is by the absolute value difference between each element of these two tuples. The array of tuples is like:

array_of_tuples = [(0.0, 6.5, 1),
     (0.0, 6.5, 4.5),
     (0.0, 6.5, 8.0),
     (0.0, 13.5, 1),
     (0.0, 13.5, 4.5),
     (0.0, 13.5, 8.0),
     (0.0, 21.0, 1),
     (0.0, 21.0, 4.5),
     (0.0, 21.0, 8.0),
     (7.0, 6.5, 1),
     (7.0, 6.5, 4.5),
     (13.5, 21.0, 8.0)]
 
 

While the query tuple is (13.1, 20.3, 8.4)

However doing: np.argmin(np.abs(array_of_tuples - (13.1, 20.3, 8.4)))

gives 8, while if I print the result without np.argmin() I clearly see that it is the last element in the array that has the least difference with the given tuple.

2

There are 2 answers

2
mozway On BEST ANSWER

You have to consider all coordinates and aggregate them into a single number (per row).

Compute the sum of squares and get the (arg)min of that:

np.argmin(((array_of_tuples - (13.1, 20.3, 8.4))**2).sum(axis=1))

Output: 11

Intermediate before argmin:

array([416.81, 377.26, 362.21, 272.61, 233.06, 218.01, 226.86, 187.31,
       172.26, 282.41, 242.86,   0.81])

As suggested by @MadPhysicist, you can also use numpy.linalg.norm to compute the norm per row:

np.argmin(np.linalg.norm(array_of_tuples-(13.1, 20.3, 8.4), axis=1))
1
Suramuthu R On

What it does is correct. See step by step

import numpy as np
array_of_tuples = [(0.0, 6.5, 1),
     (0.0, 6.5, 4.5),
     (0.0, 6.5, 8.0),
     (0.0, 13.5, 1),
     (0.0, 13.5, 4.5),
     (0.0, 13.5, 8.0),
     (0.0, 21.0, 1),
     (0.0, 21.0, 4.5),
     (0.0, 21.0, 8.0),
     (7.0, 6.5, 1),
     (7.0, 6.5, 4.5),
    (13.5, 21.0, 8.0)]
array_of_tuples = np.array(array_of_tuples)

sub = array_of_tuples -  (13.1, 20.3, 8.4)
print(sub)

'''
output:
subtracted (13.1, 20.3, 8.4)
[[-13.1 -13.8  -7.4]
 [-13.1 -13.8  -3.9]
 [-13.1 -13.8  -0.4]
 [-13.1  -6.8  -7.4]
 [-13.1  -6.8  -3.9]
 [-13.1  -6.8  -0.4]
 [-13.1   0.7  -7.4]
 [-13.1   0.7  -3.9]
 [-13.1   0.7  -0.4]
 [ -6.1 -13.8  -7.4]
 [ -6.1 -13.8  -3.9]
 [  0.4   0.7  -0.4]]
 '''

ab = np.abs(sub)
print(ab)
'''
negatives are made into positives
output:
[[13.1 13.8  7.4]
 [13.1 13.8  3.9]
 [13.1 13.8  0.4]
 [13.1  6.8  7.4]
 [13.1  6.8  3.9]
 [13.1  6.8  0.4]
 [13.1  0.7  7.4]
 [13.1  0.7  3.9]
 [13.1  0.7  0.4]
 [ 6.1 13.8  7.4]
 [ 6.1 13.8  3.9]
 [ 0.4  0.7  0.4]]
 '''

n = np.argmin(ab)
print(n)

#output 8
#Because no axis given. 0.4 is the smallest number. its index is 8 if array is converted into single dimension

Here no axis is given. And 0.4 is the smallest number and first occurence. its index is 8 if array is converted into single dimension