挣扎在论文难产的夹缝中,偷时间来筛选GPX中满足特定条件的坐标。
人在自然步道行走的时候,GPS会记录下当时行走的速度、时间,因此我们也可以根据GPS来分析人在自然状态下的一些行为特征。
凯蒂的研究中,希望通过GPS的定位,知道人们倾向于在怎样的环境中停留,于是设立了筛选坐标数据的标准(按照某篇论文设立):
在时间加总长度为300 sec的区间内,平均速度小于1.8kph的点集合。
但本质上,GPX文件是以XML格式记录地理坐标与时间,无法直接获取所需的速度,如下:
<trkpt lat="25.166045604036068" lon="121.43734443732446">
<ele>4</ele>
<time>2018-01-01T02:54:53Z</time>
</trkpt>
<trkpt lat="25.16582214687973" lon="121.43729114524088">
<ele>4</ele>
<time>2018-01-01T02:54:58Z</time>
</trkpt>
但我们可以借助GPX Viwer来获取计算后速度和时间的数据,如下:
这里在分析前,将上图红框的数据复制到excel表格中(抱歉用这么机械的做法,后来使用Mac的Automator来自动化流程,虽然没成功但这是条可行的道路,后续研究数据再大的话,可以自行用Python来计算间隔和速度)。
根据文章开头设定的标准,我们要计算出两个值:
- 区间内累积时间正好超过300 sec
- 区间内平均速度avgSpeed
在开始写code前,我们想了一个计算avgSpeed的公式:
OK,有了公式,现在来设定Python的处理流程:
- 遍历文件夹,获取所有gpx文件路径
- 依次访问gpx文件(excel格式)
- 处理Duration及Speed单位(去掉单位符号:时间为sec,速度为kph)
- 设置window概念,每次向下移动1步,获取window区间内符合基本要求的点
- 将符合的点重新生成gpx文件,输出格式为excel
- 最后将所有的excel文件写成同一份excel文件中(方便后续分析)
代码实现
我把主文件放在Github中:Python练习-给凯蒂写的gpx函数.ipynb
而合并多个excel的程序我放这里了:Python学习-合并多个Excel文件.ipynb
在这就不再放全部代码了,主要讲讲有哪些写code过程的小点:
关于正则表达式:一开始想直接用正则匹配找到所需要的时间和速度(匹配数字,去掉字母单位),但发现这样是极具耗费时间的,后来就只用replace和strip处理了。
for i in range(length_duration):
duration = data['Duration'][i]
duration_string = str(duration)
#这边没必要这么写,只要把原单位去掉,直接获取对应的数字就可以了,可使用strip()与int()
if 'sec' in duration_string:
res = float(duration_string.replace('sec', '').strip())
data['Duration'][i] = res
elif 'min' in duration_string:
res = float(duration_string.replace('min', '').strip())
data['Duration'][i] = res*60
speed = data['Speed'][i]
data['Speed'][i] = str(speed).replace('kph', '') #使用replace来加快运行的速度(re的开销太大)
关于Sliding Window:这里借用TCP或者CNN的概念,也就是用一个固定长宽的虚拟Window来选择区间,每次只处理区间内的数据,然后移动固定的步伐(Step)
sliding_window = 400 #后续可根据平均时间做计算,取整
points_list = [] #保存被筛选出来的点
# #遍历一遍原数据的所有点
length_duration = len(data['Duration'])
for i in range(length_duration):
#从第i个元素开始,用window往下滑来获取数据
index_range = i + sliding_window
window_list = []
data_slice = data[i:index_range]
关于Exception:晚上睡觉让程序自动跑,但跑到一半被Error卡死了,所以还是得加上Exception来跳过有错误的文件,第二天再来处理:
try:
data = readData(file)
print('处理它的时间、速度格式中....')
format_Data = formatData(data)
print('正在为你过滤所需要的点哦....')
new_data = pointFileter(format_Data)
except Exception as e:
print('这里有一条错了,但跳过吧:{}'.format(e))
continue
关于合并Excel:也就是把一千多个excel表格合成一个,这个用Pandas的Dataframe很好处理,根据栏位index合并就可以了:
def merge_excel(path, on=None):
"""合并数据"""
all_data = pd.DataFrame()
for f in glob.glob(path):
df = pd.read_excel(f)
all_data = all_data.append(df, ignore_index=True)
return all_data.drop_duplicates(on)
具体的话,就直接看Github的代码啦~
最后来看看凯蒂筛选出来的点的热力图效果: