import math import heapq acceptableDis = 20 acceptableTimeDiff = 30 def disDiff (item1,item2): # Pythagoras for the purpose of this example. # Real code uses real coordinates, so great circle distance is calculated. a = abs(item1['latitude'] - item2['latitude']) b = abs(item1['longitude'] - item2['longitude']) return math.sqrt(pow(a,2)+pow(b,2)) # Squaring these values makes abs() unnecessary... def removeNotMoved(locations): # This function removes all entries within acceptableTimeDiff if person hasn't moved more than acceptableDis. # Why? Because if I'm at the same bar for 4 hours, and my location is logged every 2 minutes... that's a lot of points. I'd like some of them removed. startLength = len(locations) unmovedKeys = set() # There shouldn't be any duplicates, but just in case use a set. i= 0 # Loop init while i < startLength: for j in range(i+1,len(locations)): # If point can be considered in same time window and are close enough to be considered equal if disDiff(locations[i],locations[j]) <= acceptableDis and abs(locations[i]['timestamp'] - locations[j]['timestamp']) <= acceptableTimeDiff: unmovedKeys.add(j) continue else: # Not close enough distance- or timewise. Too long has gone by or person has moved. We should move on too. # Because all points between locations[i] & locations[j] (if any) will be deleted anyway, we can continue the outer loop from i = j. i = j-1 # Minus 1 since will add 1 to i @ end of loop. break i += 1 # We want to pop starting from the end, so removed items don't influence locations of values that still need to be popped. unmovedKeys = sorted(list(unmovedKeys),reverse= True) for i in unmovedKeys: locations.pop(i) print 'Keys removed: ' + str(startLength - len(locations)) return locations def getCloseToOther(heap,compareitems): closeOnes = [] i = 0 while i < len(heap): for j in range(i+1,len(heap)): if abs(heap[i][0] - heap[j][0]) <= acceptableTimeDiff: # Points are close timewise. Let us check if the locations are close and if it's not the same person. if heap[i][1] != heap[j][1] and disDiff(compareitems[heap[i][1]][heap[i][2]],compareitems[heap[j][1]][heap[j][2]]) <= acceptableDis: closeOnes.append((i,j)) continue else: # Points aren't close enough or belong to the same person, let us move on. continue else: # Time between points is too long; we've left our time window and should move on to the next item in outer loop. i += 1 break i += 1 return closeOnes # Some data to test with. person1 = [ {'latitude' : 99998, 'longitude': 885, 'timestamp' : 9970}, {'latitude' : 99999, 'longitude': 888, 'timestamp' : 9999}, # This point is too close to person1[0] and will be removed ny removeNotMoved() {'latitude' : 99987, 'longitude': 999, 'timestamp' : 1234}, # This is the point where all persons meet on the same time. {'latitude' : 12345, 'longitude': 950, 'timestamp' : 1238}] person2 = [{'latitude' : 99999, 'longitude': 888, 'timestamp' : 6666}, {'latitude' : 66666, 'longitude': 555, 'timestamp' : 1234}, # This one is good considering timestamp, but is very far away considering distance. {'latitude' : 99979, 'longitude': 998, 'timestamp' : 1236}] # This point is ok :) person3 = [{'latitude' : 99999, 'longitude': 888, 'timestamp' : 7777}, {'latitude' : 99980, 'longitude': 995, 'timestamp' : 1234}, {'latitude' : 12345, 'longitude': 950, 'timestamp' : 1238}] # Items we want to be compared. compareItems = [person1,person2,person3] # First sort & clean. for i in range(len(compareItems)): compareItems[i].sort(key=lambda x : x['timestamp']) compareItems[i] = removeNotMoved(compareItems[i]) # Push everything into the heapq heap = [] for p in range(len(compareItems)): for i in range(len(compareItems[p])): heapq.heappush(heap, (compareItems[p][i]['timestamp'], p, i)) # Get close entries from the heapq. closeOnes = getCloseToOther(heap, compareItems) # Now format it in a way that is readable for humans. print '-----------------' print 'These ones are close both on time and place:' print '--' closeOnesReadable = [] for i in range(len(closeOnes)): # Rewrite to something readable for people. coor1Heap = heap[closeOnes[i][0]] coor2Heap = heap[closeOnes[i][1]] i1 = coor1Heap[2] i2 = coor2Heap[2] person1 = coor1Heap[1] person2 = coor2Heap[1] print 'person'+str(person1+1)+ ' & person' + str(person2+1) print str(compareItems[person1][i1]) + '\n' + str(compareItems[person2][i2]) print '--'
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question