某电子地图服务商希望获取城市路网中所有交通信号灯的红绿周期,以便为司机提供更好的导航服务。由于许多信号灯未接入网络,无法直接从交通管理部门获取所有信号灯的数据,也不可能在所有路口安排人工读取信号灯周期信息。所以,该公司计划使用大量客户的行车轨迹数据估计交通信号灯的周期。请帮助该公司解决这一问题,完成以下任务。已知所有信号灯只有红、绿两种状态。
1. 若信号灯周期固定不变,且已知所有车辆的行车轨迹,建立模型,利用车辆行车轨迹数据估计信号灯的红绿周期。附件1 中是5 个不相关路口各自一个方向连续1 小时内车辆的轨迹数据,尝试求出这些路口相应方向的信号灯周期,并按格式要求填入表1。
2. 实际上,只有部分用户使用该公司的产品,即只能获取部分样本车辆的行车轨迹。同时,受各种因素的影响,轨迹数据存在定位误差,误差大小未知。讨论样本车辆比例、车流量、定位误差等因素对上述模型估计精度的影响。附件2 中是另外5 个不相关路口各自一个方向连续1 小时内样本车辆的轨迹数据,尝试求出这些路口相应方向的信号灯周期,按同样的格式要求填入表2。
3. 如果信号灯周期有可能发生变化,能否尽快检测出这种变化,以及变化后的新周期?附件3 中是另外6 个不相关路口各自一个方向连续2 小时内样本车辆的轨迹数据,判断这些路口相应方向的信号灯周期在这段时间内是否有变化,尝试求出周期切换的时刻,以及新旧周期参数,按格式要求填入表3,并指明识别出周期变化所需的时间和条件。
4. 附件4 是某路口连续2 小时内所有方向样本车辆的轨迹数据,请尝试识别出该路口信号灯的周期。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 读取附件1中的数据
df = pd.read_csv('附件1.csv')
# 计算每辆车的行驶时长
df['duration'] = df.groupby('vehicle_id')['time'].diff().fillna(0)
# 去除行驶时长为0的数据
df = df[df['duration'] != 0]
# 以10秒为时间间隔进行分组计算,统计每个时间间隔内通过路口的车辆数
df['count'] = df.groupby(pd.cut(df['time'], np.arange(0, 3601, 10)))['vehicle_id'].transform('nunique')
# 计算每个时间间隔内通过路口的车辆数的平均值
mean_count = df['count'].mean()
# 计算每个时间间隔内通过路口的车辆数的标准差
std_count = df['count'].std()
# 根据3σ法则,设置阈值,将车辆数小于阈值的时间间隔数据剔除
threshold = mean_count - 3 * std_count
df = df[df['count'] >= threshold]
# 绘制通过路口的车辆数随时间变化的折线图
plt.figure(figsize=(10,5))
sns.lineplot(x='time', y='count', data=df)
plt.xlabel('Time (seconds)')
plt.ylabel('Number of vehicles')
plt.title('Traffic flow through intersection')
plt.show()
# 根据折线图,可以观察到大致的周期为80秒,根据附件1中的数据,将80秒作为信号灯周期的初始值
period = 80
# 计算每个时间间隔内通过路口的车辆数与信号灯周期的余数
df['remainder'] = (df['time'] // period) %