def compute_user_median(data_points, num_iter, csvwriter, current_uid):
if len(data_points) < LIMIT_POINTS: # Insufficient points for the user - don't record median
if OUTPUT_ALL_USERS:
csvwriter.writerow([current_uid, None])
else:
if SNAP_TO_USER_POINTS: # ensure median is one of the user's points
lowest_dev = float("inf")
for point in data_points:
tmp_abs_dev = objfunc(point, data_points)
if tmp_abs_dev < lowest_dev:
lowest_dev = tmp_abs_dev
test_median = point
else:
test_median = cand_median(data_points) # Calculate centroid more or less as starting point
if objfunc(test_median, data_points) != 0: # points aren't all the same
# iterate to find reasonable estimate of median
for x in range(0, num_iter):
denom = denomsum(test_median, data_points)
next_lat = 0.0
next_lon = 0.0
for y in range(0, len(data_points)):
next_lat += (data_points[y][0] * numersum(test_median, data_points[y])) / denom
next_lon += (data_points[y][1] * numersum(test_median, data_points[y])) / denom
prev_median = test_median
test_median = (next_lat, next_lon)
try:
if vincenty(prev_median, test_median).meters < DISTANCE_THRESHOLD:
break
except:
if great_circle(prev_median, test_median).meters < DISTANCE_THRESHOLD:
break
if x == num_iter - 1:
print('{0}: failed to converge. Last change between iterations was {1} meters.'.format(current_uid, great_circle(prev_median, test_median).meters))
# Check if user points are under the limit median absolute deviation
if check_median_absolute_deviation(data_points, test_median) <= LIMIT_MAD:
csvwriter.writerow([current_uid, (round(test_median[0],6), round(test_median[1],6))])
else:
if OUTPUT_ALL_USERS:
csvwriter.writerow([current_uid, None])
评论列表
文章目录