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)}