i have a numpy ndarray which looks like this
np.array(
[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866 , 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202 , 1.41421356]])
(NOTE: the arrays i generate are always in different shapes ( the shape of this array is (5, 3) but it can be (2, 2) (4, 1)... ), so this isn't a 3D coordinates array, it just generated like that)
What i need is to find the two closest values of the generated array and return their indices, in this case the values are 58.30951895 and 58.52349955, which should return the coordinates [0, 2] and [2, 2]
I've tried to use cKDtree but this isn't a coordinate array so that doesn't work in this case, how should i do this?
I'm going to be embarrassed when someone points out a one-liner, but here's a way to do it.
I flatten the array, then sort it, then find the deltas between each element. Find the minimum delta. Now, from the sorted array, I know the values of the two closest elements. argwhere then gives me the coordinates.
import numpy as np
data = np.array(
[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866 , 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202 , 1.41421356]])
order = np.sort(data.reshape(-1))
delta = np.diff(order)
am = np.argmin(delta)
print( np.argwhere(data == order[am]))
print( np.argwhere(data == order[am+1]))
Output:
C:\tmp>python x.py
[[0 2]]
[[2 2]]
If I understand it correctly their position in the array is irrelevant, so in that case is simple, put the numbers in a list in a way that it remember their original position, then sorted it and find the lowest difference between two consecutive elements
>>> import itertools
>>> def pairwise(iterable):
a,b = itertools.tee(iterable)
next(b,None)
return zip(a,b)
>>> data=[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866, 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202, 1.41421356]]
>>> linear=[ (value,x,y) for x,row in enumerate(data) for y,value in enumerate(row)]
>>> linear.sort(key=lambda x:x[0])
>>> min(pairwise(linear),key=lambda pair: abs(pair[0][0]-pair[1][0]))
((58.30951895, 0, 2), (58.52349955, 2, 2))
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With