根据上一章节的街道潮汐统计,我们可以统计得出每个街道的具体潮汐情况,并进而可以按照密度计算得到潮汐情况最为严重的区域。为了对厦门市潮汐情况与区域关系进行可视化,来对具体的潮汐情况进行直观的感受。
首先我们按照之前的代码完成具体数据读取,并对单车订单数据的时间进行提取:
bike_order['UPDATE_TIME'] = pd.to_datetime(bike_order['UPDATE_TIME'])
bike_order['DAY'] = bike_order['UPDATE_TIME'].dt.day.astype(object)
bike_order['DAY'] = bike_order['DAY'].apply(str)
bike_order['HOUR'] = bike_order['UPDATE_TIME'].dt.hour.astype(object)
bike_order['HOUR'] = bike_order['HOUR'].apply(str)
bike_order['HOUR'] = bike_order['HOUR'].str.pad(width=2,side='left',fillchar='0')
bike_order['DAY_HOUR'] = bike_order['DAY'] + bike_order['HOUR']
为了方便统计这里,我们只使用一个时间的订单数据进行绘制:
import folium
from folium import plugins
from folium.plugins import HeatMap
map_hooray = folium.Map(location=[24.482426, 118.157606], zoom_start=14)
HeatMap(bike_order.loc[(bike_order['DAY_HOUR'] == '2106') & (bike_order['LOCK_STATUS'] == 1),
['LATITUDE', 'LONGITUDE']]).add_to(map_hooray)
for data in bike_fence['FENCE_LOC'].values[::10]:
folium.Marker(
data[0, ::-1]
).add_to(map_hooray)
map_hooray
如上图,我们可以看到颜色表示为具体停车位置的热度,具体点为订车点的位置。
根据上一章节的街道潮汐统计,我们可以得到每个停车点具体的潮汐情况。如果此停车点停满了,进一步我们也可以推荐其他停车点。
我们使用下面的代码完成具体的停车点潮汐统计:
import geohash
bike_order['geohash'] = bike_order.apply(lambda x:
geohash.encode(x['LATITUDE'], x['LONGITUDE'], precision=9), axis=1)
from geopy.distance import geodesic
bike_fence['MIN_LATITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.min(x[:, 1]))
bike_fence['MAX_LATITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.max(x[:, 1]))
bike_fence['MIN_LONGITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.min(x[:, 0]))
bike_fence['MAX_LONGITUDE'] = bike_fence['FENCE_LOC'].apply(lambda x: np.max(x[:, 0]))
bike_fence['FENCE_AREA'] = bike_fence.apply(lambda x: geodesic(
(x['MIN_LATITUDE'], x['MIN_LONGITUDE']), (x['MAX_LATITUDE'], x['MAX_LONGITUDE'])
).meters, axis=1)
bike_fence['FENCE_CENTER'] = bike_fence['FENCE_LOC'].apply(
lambda x: np.mean(x[:-1, ::-1], 0)
)
import geohash
bike_order['geohash'] = bike_order.apply(
lambda x: geohash.encode(x['LATITUDE'], x['LONGITUDE'], precision=7),
axis=1)
bike_fence['geohash'] = bike_fence['FENCE_CENTER'].apply(
lambda x: geohash.encode(x[0], x[1], precision=7)
)
bike_inflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 1],
values='LOCK_STATUS', index=['geohash'],
columns=['DAY'], aggfunc='count', fill_value=0
)
bike_outflow = pd.pivot_table(bike_order[bike_order['LOCK_STATUS'] == 0],
values='LOCK_STATUS', index=['geohash'],
columns=['DAY'], aggfunc='count', fill_value=0
)
bike_remain = (bike_inflow - bike_outflow).fillna(0)
bike_remain[bike_remain < 0] = 0
bike_remain = bike_remain.sum(1)
bike_fence['DENSITY'] = bike_fence['geohash'].map(bike_remain).fillna(0)
如果乘客到了一个潮汐停车点A,如何对乘客进行引导呢?
首先为了完成停车点距离计算,还是先定义好KNN:
from sklearn.neighbors import NearestNeighbors
knn = NearestNeighbors(metric = "haversine", n_jobs=-1, algorithm='brute')
knn.fit(np.stack(bike_fence['FENCE_CENTER'].values))
然后是具体的计算逻辑进行编码:
def fence_recommend1(fence_id):
fence_center = bike_fence.loc[bike_fence['FENCE_ID']==fence_id, 'FENCE_CENTER'].values[0]
# 具体街道方向
fence_dir = fence_id.split('_')[1]
# 根据距离计算最近的20个待选位置
dist, index = knn.kneighbors([fence_center], n_neighbors=20)
# 对每个待选位置进行筛选
for idx in index[0]:
# 剔除已经有很多车的
if bike_fence.iloc[idx]['DENSITY'] > 10:
continue
# 剔除需要过街的
if fence_dir not in bike_fence.iloc[idx]['FENCE_ID']:
continue
return bike_fence.iloc[idx]['FENCE_ID']
return None
此外还需要考虑到单车没有起到停车点的情况,即推荐根据经纬度推荐最近非潮汐停车点:
def fence_recommend2(la, lo):
dist, index = knn.kneighbors([[la, lo]], n_neighbors=20)
for idx in index[0][1:]:
if bike_fence.iloc[idx]['DENSITY'] > 10:
continue
return bike_fence.iloc[idx]['FENCE_ID']
return None
综上所述我们可以将潮汐引导计划描述如下,分为两种情况:
© 2019-2023 coggle.club 版权所有 京ICP备20022947 京公网安备 11030102010643号