Home > Enterprise >  Create dictionary of shortest distances grouped by their "group"?
Create dictionary of shortest distances grouped by their "group"?

Time:10-22

I have a data file containing a bunch of location coordinates with their "code" name and their "group" letters:

code, x,      y,    group,  n,  importance
x1, 4.5692, 2.747,    P,    1,    3
x2, 2.2551, 16.7944,  H,    2,    1
x3, 15.761, 15.1464,  R,    3,    4
x4, 15.6516, 5.1249,  C,    4,    5
x5, 6.0939, 9.8601,   S,    5,    2
...

I am trying to write a function that outputs dictionary(s) of locations with minimum distance to the input location(s):

def search(inputFile,LocationCode,radius):
   from math import sin, cos, sqrt, atan2, radians
   data = dict()
   with open(inputFile) as file:        
       next(file) 
       readin = file.readlines()
       for lines in readin:
           line = lines.strip('\n')
           (code, x, y, group,n,importance) = line.split(",")
           data[code] = x,y,group,n,importance   
   float_rad = float(radius)

   to_search = []
   for i in LocationCode:
       find = data.get(i)
       to_search.append(find)

   search_x = []
   search_y = []
   for j in range(len(to_search)):
       sx = float(to_search[j][0])
       sy = float(to_search[j][1])        
       search_x.append(sx)
       search_y.append(sy)
 
   search_coord = list(zip(search_x,search_y))

   search_result = []
   distance = []

   for k in range(len(search_coord)):
       result_in_loop = []
       for i in data:
           all_x = float(data[i][0])
           all_y = float(data[i][1])
        
           if ((all_x - search_coord[k][0])**2   (all_y - search_coord[k][1])**2) < (float_rad**2):
               result_in_loop.append(data[i])

 # Here starts to find distance & minimum...        
       distance_in_loop = []
       for o in range(len(result_in_loop)):
           dx = float(result_in_loop[o][0])
           dy = float(result_in_loop[o][1])
           if dx != search_coord[k][0] or dy != search_coord[k][1]:
               distance_in_loop.append(sqrt((dx - search_coord[k][0])**2   (dy - search_coord[k][1])**2))       
       distance.append(distance_in_loop)

   testing = []
   for check in range(len(distance)):
       lmin = min(distance[check])
       testing.append(lmin)
            
   search_result.append(result_in_loop)    
#Test_run  
search('sample.csv',["x26", "x52"],3.5)

Basically, in the function first reads in the inputFile and set it in form of dictionary with "code" as its keys.

Then dict.get() the associated values of the input locationCode using for loop then append them into to_search list.

Next get the x and y coordinate values from to_search and append them into list search_x and search_y then at last zip them into a list called search_coord (its format is something similar to this: [(4.5692,2.747),(2.2551, 16.7944)])

Then it starts to search locations that are within the input radius with coordinates of the input LocationCode (which are in search_coord) being the centers, using firstly a for loop on search_coord then a nested loop on the original data dictionary that runs the calculation to find locations within the radius. The data locations that are within the radius will then put into result_in_loop.

Later I made it to calculate distances of locations from the central input coordinates, append to distance_in_loop then finally put lists of values to distance outside the for k in range(len(search_coord)) loop which did return me a list such as [[dist_1,dist_2,dist_3...],[dist_1,dist_2,dist_3...]].

But now I am not sure how to create dictionaries that find minimum distance in distance then use data's group to group the locations values and in forms of something such as this:

>>  [{'H': ('x7', 2.3034), 'R': ('x81', 0.7736), 'C': ('x99', 2.0607), 'S': ('x65', 1.556)}, {'P': ('x46', 2.4717), 'H': ('x22', 1.4374), 'R': ('x88', 2.5338), 'S': ('x30', 2.0482)}]

In the other words, trying to make the function return lists containing dictionaries in forms of:

{ "group" : ("code" , the_distance) }

And, already tried use min() on distance but is confused on how to make a relation to their group (to make distance values related to group and x,y values in the original data dictionary)...

CodePudding user response:

Here is relative simple code to solve your problem if you can pack the data from the file in a structure like:

{'group_name':('item_name',x,y)} -> with x,y as coordinates

Then you can use the following function:

def find_min_distances(coordinates,data_dict):
    dx,dy=coordinates
    result={}
    for k, v in data_dict.items():
        for i in v:
            d=((i[1]-dx)**2 (i[2]-dy)**2)**0.5
            print(d,i[0],k) # just to control the result print can be removed later on!
            if k in result:
                if result[k][1]>d: # >= may make also sense depending what you want
                    result[k]=(i[0],d)
            else:
                result[k]=(i[0],d)
    return result

I tested with:

b={'H':[('x2',3.4,8.9),('x3',4.9,18.9)],'B':[('x4',1.4,1.9),('x5',14.9,8.9)],'C':[('x6',1.4,8.9),('x7',4.9,18.9)]}
print(find_min_distances((1,2),b))

Delivering:

{'C': ('x6', 6.911584478250989), 'B': ('x4', 0.41231056256176596), 'H': ('x2', 7.305477397131552)}
  • Related