您好我使用Python来计算用户走路的距离。我决定他们是否以速度行走。如果速度低于5米/秒,他们会考虑走路。但是我在制作这个功能时遇到了麻烦。你能帮我解决一下这个功能吗?到目前为止,我的输入是手动放入另一个名为“make_timestamped_loc”的函数,并通过名为“total_dist”的函数计算距离。这是我的代码......
import ctp17hw1
dic_loc = []
def make_timestamped_loc(La, Lng, TS):
new_loc = {}
new_loc['latitude'] = La
new_loc['longitude'] = Lng
new_loc['timestamp'] = int(TS)
dic_loc.append(new_loc)
make_timestamped_loc(37.481236, 126.952733, 1483196400)
make_timestamped_loc(37.310045, 127.101255, 1408323255)
make_timestamped_loc(37.383065, 126.672596, 1508322531)
make_timestamped_loc(37.383065, 116.672596, 1444999230)
# make_timestamped_loc(37.383065, 112.672596, 1444999230) #error sample
print(dic_loc)
def sort_locs(sortingDict):
newlist = sorted(sortingDict, key=lambda k: k['timestamp'])
for i in range(len(dic_loc) - 1, -1, -1):
dic_loc.remove(dic_loc[i])
for i in range(len(newlist)):
for j in range(len(newlist)):
if (newlist[i]['timestamp'] == newlist[j]['timestamp']
and (newlist[i]['latitude'] != newlist[j]['latitude'] or newlist[i]['longitude'] != newlist[j]['longitude'])
and i != j):
raise ValueError('There is duplicated location on same time!')
sortingDict.append(newlist[i])
sort_locs(dic_loc)
def total_dist(sortedDict):
totalDist = 0;
for i in range(len(sortedDict) - 1):
sm = ctp17hw1.dist(sortedDict[i]["latitude"], sortedDict[i]["longitude"], sortedDict[i+1]["latitude"], sortedDict[i+1]["longitude"])
totalDist = totalDist + sm
return totalDist
total_dist(dic_loc)
print(total_dist(dic_loc))
ctp17hw1是另一个用于计算距离的文件。 因为Unix的时间,我很困惑。 非常感谢你
答案 0 :(得分:0)
使用Getting distance between two points based on latitude/longitude和Iterate a list as pair (current, next) in Python中提供的解决方案,我能够构建这个问题的Pythonic方法:
import itertools
from collections import namedtuple
from math import sin, cos, sqrt, atan2, radians
Location = namedtuple('Location', ['long', 'lat', 'time'])
all_locations = [
Location(lat=37.481236, long=126.952733, time=1488323400),
Location(lat=37.310045, long=127.101255, time=1488323255),
Location(lat=37.383065, long=126.672596, time=1488323531),
Location(lat=37.383065, long=116.672596, time=1488323230),
]
def distance(loc_a, loc_b):
"""Extracted from: https://stackoverflow.com/questions/19412462"""
R = 6373.0
lat_a, lat_b = radians(loc_a.lat), radians(loc_b.lat)
long_a, long_b = radians(loc_a.long), radians(loc_b.long)
dlat = lat_b - lat_a
dlong = long_b - long_a
a = sin(dlat / 2)**2 + cos(lat_a) * cos(lat_b) * sin(dlong / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return R * c
def pairwise(iterable):
"""Extracted from: https://stackoverflow.com/questions/5434891"""
a, b = itertools.tee(iterable)
next(b, None)
return zip(a, b)
sorted_locations = sorted(all_locations, key=lambda l: l.time)
total_distance = sum(distance(a, b) for a, b in pairwise(sorted_locations))
delta_time = sorted_locations[-1].time - sorted_locations[0].time
print(total_distance, delta_time, total_distance / delta_time)
使用namedtuple不是强制性的,但我觉得它会简化代码。名为tuple的FTR是仅包含声明字段的简单结构(此处为long,lat和time)。
pairwise
函数允许迭代2对列表(即当前和下一个元素)。通过按时间在排序的位置列表上使用它,我可以轻松地评估距离。基本上是:
sorted_locations = [l1, l2, l3]
distances = [distance(a, b) for a, b in pairwise(sorted_locations)]
# equivalent to [distance(l1, l2), distance(l2, l3)]
total_distance = sum(distances)
不使用中间列表将减少内存消耗(在示例中与大型列表相关)无关紧要。我还可以声明一个距离生成器(使用列表推导的(distance(a, b) for ...)
insteand)。
注意我没有预先计算long / lat的radians
,并且对于列表的非extrem元素计算它们2次。这可能会有一点性能提升,但我主要想在这里保持算法简单。