My objective is the following: given a list of numbers (int. or float) (1D), I need to find N amount of numbers that are closest to
each other in this list. For example:
Given sample_list = [1, 8, 14, 15, 17, 100, 35]
and N = 3
, the desired function should return a list of [14, 15, 17]
, because the 3 "nearest neighbors" in this list are 14, 15, and 17.
So far, I have tackled the problem the following way, being forced to make several compromises in my approach (after unsuccessfully searching for a solution online):
I decided to iterate over each number in the list and find its N amount of "nearest neighbors". These "nearest neighbors" are stored in a new list and then compared with other such lists using numpy.diff function. The list with the smallest amount resulted from numpy.diff
is the winner.
At the base of my solution is the code provided by this article on geeksforgeeks.org. The idea to use numpy.diff
function came from here on stackoverflow.com
My (working) monstrosity can be found below:
import numpy as np
def find_nn_in_list_1D(list_for_search, num_neighbors_desired):
list_iterator = list_for_search.copy()
list_mod = list_for_search.copy()
neighbor_storage_list = []
neighbor_eval_score = 999_999_999
for number in list_iterator:
neighbor_nil = list_mod[min(range(len(list_mod)), key = lambda i: abs(list_mod[i] - number))]
neighbor_storage_list.append(neighbor_nil)
list_mod.remove(neighbor_nil)
for num_neighbor in range(num_neighbors_desired):
neighbor = list_mod[min(range(len(list_mod)), key = lambda i: abs(list_mod[i] - number))]
neighbor_storage_list.append(neighbor)
list_mod.remove(neighbor)
neighbor_storage_list.sort()
if neighbor_eval_score > abs(sum(np.diff(neighbor_storage_list))):
neighbor_eval_score = abs(sum(np.diff(neighbor_storage_list)))
nearest_neighbors_list = neighbor_storage_list.copy()
list_mod = list_for_search.copy()
neighbor_storage_list = []
return nearest_neighbors_list
I am very certain that there is a much better way of solving this issue.
Even though it works, I would like to write better, cleaner code.
If you have a better solution than mine please share below. Thank you for your time!