GPS轨迹缺失值填补
从硬件设备收集位置信息时,由于设备问题或传输问题,会发生位置信息缺失情况,需要根据前面已有的数据补充缺失数据,以便于后续的分析处理。
本文用Kalman滤波来填补缺失位置信息。
例如有15个GPS位置点,每个点之间的收集间隔时间为一小时。
ship_data = np.array([[ 30.6751, 122.191 ],)
[ 30.7723, 122.207 ],
[ 30.9336, 122.221 ],
[ 31.0166, 122.198 ],
[ 31.0634, 122.113 ],
[ 31.0812, 122.033 ],
[ 31.1106, 121.972 ],
[ 31.1321, 121.934 ],
[ 31.1425, 121.915 ],
[ 31.167 , 121.871 ],
[ 31.2117, 121.817 ],
[ 31.283 , 121.745 ],
[ 31.366 , 121.634 ],
[ 31.4468, 121.482 ],
[ 31.5351, 121.361 ]]
将第11到14的3个点设置为缺失,然后用kalman滤波来填补。
设置缺失值时需要用到numpy 的ma类。
```python
from numpy import ma
from pykalman import KalmanFilter
km_data = ma.asarray(ship_data)
km_data[11:14]=ma.masked
```
此时km_data=masked_array(
data=[[30.6751, 122.191],
[30.7723, 122.207],
[30.9336, 122.221],
[31.0166, 122.198],
[31.0634, 122.113],
[31.0812, 122.033],
[31.1106, 121.972],
[31.1321, 121.934],
[31.1425, 121.915],
[31.167, 121.871],
[31.2117, 121.817],
[--, --],
[--, --],
[--, --],
[31.5351, 121.361]],
mask=[[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[False, False],
[ True, True],
[ True, True],
[ True, True],
[False, False]],
fill_value=1e+20)
然后用kalman滤波器进行处理
init_mean = np.mean(ship_data[0:11],axis=0)
kf = KalmanFilter(initial_state_mean=init_mean, n_dim_obs=2)
result,_ = kf.em(km_data).smooth(km_data)
result是smooth后的位置信息。
array([[ 30.71337729, 122.20059021],
[ 30.79026542, 122.2087261 ],
[ 30.91422361, 122.20673372],
[ 30.9988365 , 122.17886039],
[ 31.05295974, 122.10927779],
[ 31.08223278, 122.03751336],
[ 31.11014741, 121.97826347],
[ 31.13106912, 121.93798154],
[ 31.14553269, 121.91038793],
[ 31.17245686, 121.866536 ],
[ 31.21827118, 121.80480735],
[ 31.2931099 , 121.70132513],
[ 31.36794862, 121.59784291],
[ 31.44278734, 121.49436068],
[ 31.51762607, 121.39087846]])
创建KalmanFilter时initial_stat_mean 取前11个数据的均值,n_dim_obs取2,应为要处理的数据有两列,经度和纬度。
将原始数据和经过kalman滤波器处理后的数据点画图做一个比较。蓝色为真实点,黄色为Kalman滤波器处理后的点。
plt.scatter(ship_data[:,0],ship_data[:,1],label='true')
plt.scatter(result[:,0],result[:,1],label='klm')
plt.legend()
![](https://img.haomeiwen.com/i15630403/05150c5df34bf041.png)