Reputation: 356
I have GPS coordinates for RRH and BBU:
RRH: [[41.38988253, 2.129556023, '1'], [41.38745915, 2.126436603, '2'], [41.3929439, 2.143336753, '3'], [41.39109767, 2.135616075, '4'], [41.39496903, 2.138040811, '5'], [41.39414659, 2.137729336, '6'], [41.38440257, 2.119681252, '7'], [41.3535301, 2.144453223, '8'], [41.35552416, 2.137000697, '9'], [41.35258318, 2.148086036, '10'], [41.35130853, 2.140463315, '11'], [41.38765528, 2.121350735, '12'], [41.36445154, 2.132837518, '13'], [41.36144746, 2.130147294, '14'], [41.34995663, 2.144620381, '15'], [41.38124426, 2.118779226, '16'], [41.36352164, 2.134464983, '17'], [41.3904652, 2.13343991, '18'], [41.39335171, 2.135858918, '19'], [41.38860314, 2.135873516, '20'], [41.39195119, 2.139388009, '21'], [41.40584116, 2.215194359, '22'], [41.41060962, 2.22285246, '23'], [41.40801101, 2.211823094, '24'], [41.40174968, 2.213648607, '25'], [41.40881323, 2.215466548, '26'], [41.40876677, 2.217668089, '27'], [41.40393753, 2.190354235, '28'], [41.40309294, 2.191549143, '29'], [41.40421413, 2.193764487, '30'], [41.40198954, 2.188620978, '31'], [41.40540358, 2.187300951, '32'], [41.3988891, 2.190027392, '33'], [41.40488006, 2.184768114, '34'], [41.40656225, 2.186155734, '35'], [41.4032534, 2.183736817, '36'], [41.40742083, 2.191097044, '37'], [41.39982978, 2.194269803, '38'], [41.38723668, 2.129851845, '39'], [41.39034394, 2.124049766, '40'], [41.38648798, 2.122911378, '41'], [41.40668683, 2.193266381, '42'], [41.41341636, 2.218966707, '43'], [41.41339722, 2.222205598, '44'], [41.39375604, 2.140802106, '45'], [41.38818833, 2.128579772, '46'], [41.38589634, 2.115121354, '47'], [41.39037831, 2.137155264, '48'], [41.40888641, 2.218998806, '49'], [41.41149706, 2.227529451, '50'], [41.407576, 2.217833448, '51'], [41.40577599, 2.190513005, '52'], [41.40461468, 2.190262216, '53'], [41.36564597, 2.131829909, '54'], [41.36489012, 2.131611604, '55'], [41.3655079, 2.13350979, '56'], [41.3545356, 2.138947744, '57'], [41.35294958, 2.138810688, '58'], [41.35525513, 2.142080929, '59'], [41.38541285, 2.117792843, '60'], [41.40350203, 2.16165616, '61'], [41.39407746, 2.163295498, '62'], [41.40256563, 2.159653646, '63'], [41.40345137, 2.158732677, '64'], [41.40573486, 2.160594926, '65'], [41.40544246, 2.158677166, '66'], [41.4042025, 2.156580309, '67'], [41.40639032, 2.156391287, '68'], [41.40497179, 2.154232881, '69'], [41.40737523, 2.158183354, '70'], [41.40208867, 2.154838201, '71'], [41.40271803, 2.152349074, '72'], [41.40072331, 2.157982016, '73'], [41.40094072, 2.152824619, '74'], [41.40515581, 2.151148606, '75'], [41.39161495, 2.154777093, '76'], [41.39164912, 2.1502518, '77'], [41.3933277, 2.153140256, '78'], [41.38964343, 2.155062515, '79'], [41.39104607, 2.158508685, '80'], [41.38904977, 2.15814747, '81'], [41.38731735, 2.155917023, '82'], [41.38731395, 2.151280403, '83'], [41.38455081, 2.148338702, '84'], [41.38051089, 2.1491282, '85'], [41.38050935, 2.154302387, '86'], [41.3830847, 2.153219841, '87'], [41.37746396, 2.152994102, '88'], [41.37864266, 2.158372984, '89'], [41.38162664, 2.160132284, '90'], [41.38477989, 2.157736848, '91'], [41.39646026, 2.166359429, '92'], [41.39531549, 2.161977489, '93'], [41.39386582, 2.165235745, '94'], [41.39303263, 2.168665537, '95'], [41.39052591, 2.16766681, '96'], [41.39528298, 2.170973353, '97'], [41.39307377, 2.173802557, '98'], [41.39026389, 2.172233558, '99'], [41.39198357, 2.176844408, '100'], [41.38705505, 2.168349986, '101'], [41.38580475, 2.169337344, '102'], [41.38489202, 2.170894091, '103'], [41.38374847, 2.170944317, '104'], [41.38320131, 2.171871154, '105'], [41.38229848, 2.171974446, '106'], [41.38164839, 2.172520899, '107'], [41.38141647, 2.173589097, '108'], [41.38060403, 2.173336928, '109'], [41.37981981, 2.174131261, '110'], [41.37907178, 2.175426808, '111'], [41.37856088, 2.176158937, '112'], [41.37770398, 2.175726781, '113'], [41.37723853, 2.176857279, '114'], [41.37667486, 2.177878565, '115'], [41.38657664, 2.171501454, '116'], [41.38796178, 2.17078609, '117'], [41.38852804, 2.172406557, '118'], [41.38889536, 2.168287986, '119'], [41.39089217, 2.165811636, '120'], [41.39265104, 2.163642299, '121'], [41.39437496, 2.161499581, '122'], [41.39594399, 2.159692488, '123'], [41.38726061, 2.17415253, '124'], [41.3867827, 2.17525906, '125'], [41.38613137, 2.175649167, '126'], [41.3854995, 2.176295834, '127'], [41.3851489, 2.176954444, '128'], [41.38455147, 2.175213232, '129'], [41.38377194, 2.174609471, '130'], [41.38284373, 2.176761578, '131'], [41.38426326, 2.178683726, '132'], [41.38321941, 2.179508837, '133'], [41.38554138, 2.173372772, '134'], [41.38070946, 2.17799329, '135'], [41.37906733, 2.1798861, '136'], [41.38106167, 2.181434062, '137'], [41.38414004, 2.18409775, '138'], [41.38487256, 2.185618739, '139'], [41.3829069, 2.186158478, '140'], [41.39647318, 2.158142169, '141'], [41.39541995, 2.156254351, '142'], [41.39543435, 2.153929413, '143'], [41.39442252, 2.152344159, '144'], [41.39458675, 2.150402206, '145'], [41.39349639, 2.148882225, '146'], [41.39309984, 2.146997441, '147'], [41.39269047, 2.145737024, '148'], [41.39216, 2.144617541, '149'], [41.39212191, 2.143791101, '150'], [41.39151727, 2.141423138, '151'], [41.39087681, 2.138892682, '152'], [41.37951535, 2.123255434, '153'], [41.38234159, 2.122750756, '154'], [41.38076059, 2.121654553, '155'], [41.38158784, 2.12511256, '156'], [41.37973609, 2.142609535, '157'], [41.38070643, 2.140787318, '158'], [41.37912693, 2.140125029, '159'], [41.38558235, 2.196101422, '160'], [41.38373742, 2.194310782, '161'], [41.38872536, 2.191850873, '162'], [41.39104446, 2.189013813, '163'], [41.38964624, 2.183705985, '164'], [41.3756532, 2.176672921, '165'], [41.37445512, 2.174137286, '166'], [41.37511963, 2.172150053, '167'], [41.37469855, 2.170009728, '168'], [41.37522149, 2.167265619, '169'], [41.37477745, 2.164891338, '170'], [41.37525678, 2.163534026, '171'], [41.37469573, 2.1615999, '172'], [41.37530681, 2.159561563, '173'], [41.37476511, 2.157728066, '174'], [41.37530116, 2.155975208, '175'], [41.3752681, 2.152972091, '176'], [41.37559207, 2.15040038, '177'], [41.38912147, 2.200525494, '178'], [41.37606258, 2.149193449, '179'], [41.37382267, 2.148593761, '180'], [41.37365726, 2.150790153, '181'], [41.3722869, 2.148909567, '182'], [41.37338846, 2.154652807, '183'], [41.3763164, 2.189202428, '184'], [41.37797628, 2.188494739, '185'], [41.37944773, 2.187923778, '186'], [41.37859323, 2.191248351, '187'], [41.38123405, 2.187259818, '188'], [41.37918489, 2.155172675, '189'], [41.38143976, 2.156791124, '190'], [41.38303894, 2.160313106, '191'], [41.38562105, 2.162507838, '192'], [41.38627958, 2.164671358, '193'], [41.38811461, 2.164473477, '194'], [41.38904783, 2.162547839, '195'], [41.38867274, 2.159556719, '196'], [41.37814521, 2.170763199, '197'], [41.39856273, 2.181141831, '198'], [41.39706339, 2.177725078, '199'], [41.39543338, 2.174173142, '200'], [41.40595965, 2.196085956, '201'], [41.40590057, 2.198644551, '202'], [41.40822011, 2.201575706, '203'], [41.40690119, 2.202357761, '204'], [41.408396, 2.204834417, '205'], [41.40866122, 2.207238278, '206'], [41.40847209, 2.206574199, '207'], [41.40842553, 2.20897442, '208'], [41.40989058, 2.211958916, '209'], [41.4078404, 2.199451041, '210'], [41.42994945, 2.199672708, '211'], [41.42871317, 2.197970163, '212'], [41.42886609, 2.204068146, '213'], [41.42635501, 2.200254099, '214'], [41.42572176, 2.208256698, '215'], [41.42727818, 2.204374155, '216'], [41.42332817, 2.196548327, '217'], [41.4250889, 2.197223711, '218'], [41.42694172, 2.195373298, '219'], [41.43267828, 2.197860268, '220'], [41.40703161, 2.153612625, '221'], [41.40816405, 2.155696109, '222'], [41.40867073, 2.152077178, '223'], [41.41021455, 2.149881192, '224'], [41.40856448, 2.147062842, '225'], [41.41058356, 2.147931309, '226'], [41.40941309, 2.145606571, '227'], [41.4070378, 2.146164866, '228'], [41.41057942, 2.158529623, '229'], [41.40915937, 2.159776124, '230'], [41.39910639, 2.157642354, '231'], [41.39946885, 2.1601829, '232'], [41.39742936, 2.16204943, '233'], [41.39786889, 2.165887234, '234'], [41.39909312, 2.168827544, '235'], [41.39967085, 2.173128868, '236'], [41.40094963, 2.176077127, '237'], [41.40239839, 2.174188933, '238'], [41.40303716, 2.178815456, '239'], [41.40105048, 2.180930452, '240'], [41.40180775, 2.16680983, '241'], [41.40074303, 2.165274684, '242'], [41.40160211, 2.170797932, '243'], [41.40527925, 2.175215203, '244'], [41.40578643, 2.181131991, '245'], [41.4057811, 2.165305951, '246'], [41.40632458, 2.169821608, '247'], [41.40947235, 2.165138472, '248'], [41.40615597, 2.16290471, '249'], [41.40899559, 2.163609208, '250'], [41.41162898, 2.164328687, '251'], [41.40415872, 2.167584134, '252'], [41.40934147, 2.172128646, '253'], [41.41095553, 2.170031558, '254'], [41.40775853, 2.166686358, '255'], [41.40785995, 2.174679854, '256'], [41.41081219, 2.174542492, '257'], [41.40721475, 2.177817663, '258'], [41.40971316, 2.1789005, '259'], [41.41183357, 2.177744727, '260'], [41.38720667, 2.197712891, '261'], [41.38797421, 2.19511995, '262'], [41.38954698, 2.197268152, '263'], [41.39170675, 2.199937827, '264'], [41.39335424, 2.202052066, '265'], [41.38124352, 2.192809131, '266'], [41.37075116, 2.156721231, '267'], [41.37003354, 2.150872323, '268'], [41.36598669, 2.137806, '269'], [41.3671078, 2.14043114, '270'], [41.36629935, 2.136886419, '271'], [41.40244212, 2.193566064, '272'], [41.40338457, 2.197149137, '273'], [41.40147665, 2.197388361, '274'], [41.40429076, 2.199376949, '275'], [41.39955167, 2.195996457, '276'], [41.40156317, 2.199910671, '277'], [41.39941119, 2.198182841, '278'], [41.39747841, 2.197920138, '279'], [41.39916766, 2.200553512, '280'], [41.39742986, 2.200637056, '281'], [41.39771604, 2.202732102, '282'], [41.39760922, 2.204672685, '283'], [41.39649475, 2.203286769, '284'], [41.39715776, 2.205623271, '285'], [41.42645327, 2.202375412, '286'], [41.42849034, 2.20477867, '287'], [41.42781111, 2.20620115, '288'], [41.42467475, 2.203392208, '289'], [41.42710869, 2.207678204, '290'], [41.42416437, 2.205934769, '291'], [41.42370113, 2.210090139, '292'], [41.40610086, 2.149617997, '293'], [41.40662625, 2.148883385, '294'], [41.4077921, 2.150012055, '295'], [41.40693465, 2.15091706, '296'], [41.40565244, 2.150263277, '297'], [41.4045975, 2.150030929, '298'], [41.4038193, 2.150290792, '299'], [41.40210728, 2.150488432, '300']]
BBU: [[41.38227061, 2.128611835, '1'], [41.39517376, 2.147391488, '2'], [41.40538329, 2.156731836, '3'], [41.40832257, 2.168647219, '4'], [41.40323209, 2.206633545, '5'], [41.39397106, 2.193518883, '6'], [41.38212698, 2.189586642, '7'], [41.41882802, 2.199257871, '8'], [41.35910284, 2.136974551, '9'], [41.38131931, 2.176102407, '10'], [41.38918794, 2.177094309, '11'], [41.39325006, 2.156269437, '12'], [41.38385621, 2.161888675, '13'], [41.37208181, 2.162537181, '14'], [41.376809, 2.144989163, '15'], [41.40015888, 2.178641263, '16'], [41.42046079, 2.182838054, '17'], [41.40103642, 2.161985998, '18']]
The code I've written, calculates all possible distances between RRHs and BBUs and stores it in a multidimension lists with the following structure:
# Structure variables "distances"
distances = [[calculated_distance, BBU_id, RRH_id]]
Example: [[115.6, 3, 68]]
To sum up, I have a list of sublists, of 5400 entries.
What I'd like now is to store, out of the distances varibles, in another list, let's calle it "connected_sites", the minimum distance of each RRH to a BBU. So it will end up with a list of 300 sublists.
I don't know how to pick from all the distances the minimums ones for every RRH.
This is the code:
# Libraries
import math
import csv
import operator
# -------------------------------- FUNCTIONS ---------------------------------
# Calculates the distance between two GPS coordinates
def haversine(coord1, coord2):
R = 6372800 # Earth radius in meters
lat1, lon1 = coord1
lat2, lon2 = coord2
phi1, phi2 = math.radians(lat1), math.radians(lat2)
dphi = math.radians(lat2 - lat1)
dlambda = math.radians(lon2 - lon1)
a = math.sin(dphi/2)**2 + \
math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2
return 2*R*math.atan2(math.sqrt(a), math.sqrt(1 - a))
# Convert GPS coordinates from str to float
def coord2float(l):
for i in range(len(l)):
l[i][0]=float(l[i][0])
l[i][1]=float(l[i][1])
return l
# MAIN
# Importing GPS coordinates
RRH = []
BBU = []
i = 0
with open('sites.csv', newline='\n') as csvfile:
sites = csv.reader(csvfile, delimiter=';')
for row in sites:
if i < 300:
RRH.append(row)
i+=1
else:
BBU.append(row)
# # Converting file coordinates into floats
RRH = coord2float(RRH)
BBU = coord2float(BBU)
# Calculating the distances between BBU and RRH
distances = []
for i in range(len(BBU)):
for j in range(len(RRH)):
coord1 = (BBU[i][0],BBU[i][1])
coord2 = (RRH[j][0],RRH[j][1])
dist = haversine(coord1, coord2)
distances.append([float("%.1f" % dist),
int(BBU[i][2]),
int(RRH[j][2])])# Convert distance to float
distances = sorted(distances, key=operator.itemgetter(0), reverse=False)
Upvotes: 2
Views: 169
Reputation: 1253
So in my mind itertools.groupby
will solve this problem. I made a copy of the data you provided, put it into the sites.csv
and made a few tweaks to the code and added the lines needed to create connected_sites
:
# Libraries
import csv
from itertools import groupby
def haversine(coord1, coord2):
"""Calculates the distance between two GPS coordinates"""
from math import sin, cos, atan2, sqrt, radians
R = 6372800 # Earth radius in meters
lat1, lon1 = coord1
lat2, lon2 = coord2
phi1, phi2 = radians(lat1), radians(lat2)
dphi = radians(lat2 - lat1)
dlambda = radians(lon2 - lon1)
a = sin(dphi / 2)**2 + cos(phi1) * cos(phi2) * sin(dlambda / 2)**2
return 2 * R * atan2(sqrt(a), sqrt(1 - a))
def coord2float(lst):
"""Convert GPS coordinates from str to float"""
for ll in lst:
ll[0] = float(ll[0])
ll[1] = float(ll[1])
return lst
# MAIN
# Importing GPS coordinates
RRH = []
BBU = []
i = 0
with open('sites.csv', newline='') as csvfile:
sites = csv.reader(csvfile, delimiter=';')
for row in sites:
if not row:
continue
if i < 300:
RRH.append(row)
i += 1
else:
BBU.append(row)
# # Converting file coordinates into floats
RRH = coord2float(RRH)
BBU = coord2float(BBU)
# Calculating the distances between BBU and RRH
distances = []
for i in range(len(BBU)):
for j in range(len(RRH)):
coord1 = (BBU[i][0], BBU[i][1])
coord2 = (RRH[j][0], RRH[j][1])
dist = haversine(coord1, coord2)
distances.append([float("%.1f" % dist),
int(BBU[i][2]),
int(RRH[j][2])]) # Convert distance to float
Adding code to first sort the distances calculated with respect to the RRH id. Then use groupby
to iterate over each RRH id to calculate the minimum distance using min
on the distances calculated for each RRH id:
distances.sort(key=lambda dd: dd[2])
connected_sites = []
for rrh_id, grouped_bbu in groupby(distances, key=lambda dd: dd[2]):
dist4k = list(grouped_bbu)
min_dist = min(dist4k, key=lambda dd: dd[0])
connected_sites.append([min_dist, rrh_id])
print(f'Number connected sites: {len(connected_sites)}')
print(f'First two minimum distances: {connected_sites[:2]}')
print(f'Distances for first two sites: {distances[:36]}')
Running this code on the input data gives the output below. On insecption it is clear that the calculated minimum distance is correct.
Number connected sites: 300
First two minimum distances: [[[850.3, 1, 1], 1], [[605.0, 1, 2], 2]]
Distances for first two sites: [[850.3, 1, 1], [1600.4, 2, 1],
[2848.5, 3, 1], [3852.8, 4, 1], [6600.3, 5, 1], [5356.6, 6, 1],
[5083.3, 7, 1], [6646.7, 8, 1], [3479.1, 9, 1], [3999.4, 10, 1],
[3967.6, 11, 1], [2260.3, 12, 1], [2780.1, 13, 1], [3390.6, 14, 1], [1942.5, 15, 1], [4252.1, 16, 1], [5597.0, 17, 1], [2976.7, 18, 1], [605.0, 1, 2], [1947.7, 2, 2], [3219.3, 3, 2], [4217.6, 4, 2],
[6917.6, 5, 2], [5644.3, 6, 2], [5303.2, 7, 2], [7005.9, 8, 2],
[3274.3, 9, 2], [4200.6, 10, 2], [4231.6, 11, 2], [2571.4, 12, 2], [2985.5, 13, 2], [3464.5, 14, 2], [1949.5, 15, 2], [4579.3, 16, 2], [5967.8, 17, 2], [3328.5, 18, 2]]
Upvotes: 1