车辆驾驶行为分析——比赛复盘(一)地图生成.

最近比赛结果出来了,所以我打算对比赛做一个复盘,作日后参考之用。

我们的队伍有幸拿了全国二等奖,我在其中负责的是算法以及编程实现

因为整个比赛时长只有七天,算法没有时间做特别多的优化,所以代码的质量可能不是特别高

本人水平有限,若有缺漏之处欢迎指正

研究问题

  1. 利用附件 1 所给数据,提取并分析车辆的运输路线以及其在运输过程中的速度、加速度等行车状态。提交附表中 10 辆车每辆车每条线路在经纬度坐标系下的运输线路图及对应的行车里程、平均行车速度、急加速急减速情况。

  2. 利用附件 1 所给数据,挖掘每辆运输车辆的不良驾驶行为,建立行车安全的评价模型,并给出评价结果。

  3. 综合考虑运输车辆的安全、效率和节能,并结合自然气象条件与道路状况等情况, 为运输车辆管理部门建立行车安全的综合评价指标体系与综合评价模型。

附表

序号 1 2 3 4 5 6 7 8 9 10
车牌号 AA00002 AB00006 AD00003 AD00013 AD00053 AD00083 AD00419 AF00098 AF00131 AF00373

数据说明

  1. 附件 1 给出 450 辆运输车辆的行车轨迹采集数据,由于采集设备精度,实际采集数据可能存在某些异常。
序号 指标名称 指标说明 说明
1 vehicleplatenumber 车牌号码
2 device_num 设备号
3 direction_angle 方向角 范围:0-359(方向角指从定位点的正北方向 起,以顺时针方向至行驶方向间的水平夹角)
4 lng 经度 东经
5 lat 纬度 北纬
6 acc_state ACC 状态 点火 1/熄火 0
7 right_turn_signals 右转向灯 灭 0/开 1
8 left_turn_signals 左转向灯 灭 0/开 1
9 hand_brake 手刹 灭 0/开 1
10 foot_brake 脚刹 无 0/有 1
11 location_time 采集时间
12 gps_speed GPS 速度 单位:km/h
13 mileage GPS 里程 单位:km
  1. 附件 2 给出 2018 年 7 月 30 日至 2018 年 10 月 10 日全国主要城市的自然气象数据
序号 指标名称 指标说明 说明
1 province 省/自治区/直辖市
2 prefecture_city 地级市
3 county 县级市/县
4 wind_direction 风向
5 wind_power 风力
6 high_temp 最高温度
7 low_temp 最低温度
8 conditions 天气状况 如:多云、晴、雨、雪
9 relative_humidity 相对湿度
10 precipitation 降水量 单位:mm
11 record_date 采集日期
  1. 在车辆运输过程中,不良驾驶行为主要包括疲劳驾驶、急加速、急减速、怠速预热、超长怠速、熄火滑行、超速、急变道等。

数据类型样例

下面附上数据的样例截图:

开始解题

首先分析题目,题目中要完成的目标主要分为三块:

  • 根据 .csv 中的经纬度数据生成路线图
  • 根据数据对车辆的疲劳驾驶、急加减速等因素进行多维度的综合评价
  • 结合天气对车辆的驾驶行为进行评价

所以解构后问题就比较明了了,接下来进行代码实现。

首先老样子,贴上整个项目的结构图

下面解释一下:

  • _dataset 是存放 .csv 数据的文件夹,后续分析的数据皆从此文件夹读取
  • map 用于存放生成的地图文件
  • module 是存放主要代码的文件夹,由外部 main.py 调用
  • main.py 是主文件,直接运行此文件可以调用 module 里面的包进行运算

为什么要把 main.py 单独出来呢? 因为队友也要参与代码调试和数据生成,而他们对 Python 不是很熟悉。所以我把 main.py 单独出来方便队友使用,比较简洁直观。

生成地图

如何根据经纬度来生成地图呢?网上有许多的方法,有用 Pyecharts 的,也有用 matplotlib 的,而因为我需要作出一个可交互的地图,所以最后使用了 folium

folium 需要通过 pip 安装。

首先要获取 _dataset 中的 .csv 数据文件列表,以便后面生成地图和进行数据分析。

代码如下:

    @staticmethod
    def get_csv_list(_dir):  # 获取_dataset中csv文件目录

        csv_list = []
        _dir = _dir + '\\_dataset'
        for dir_path, dirname, filenames in os.walk(_dir):
            for filename in filenames:
                if '.csv' in os.path.split(filename)[-1]:  # 判断是 .csv 文件则写入列表
                    csv_list.append(os.path.join(filename))

        return csv_list  # 传回列表

如果数据量多并且需要多次调用读取数据,可以先将目录保存在 .txt 文件中,然后后面直接读取该文件即可。

接着,把读取到的文件名传入 data_input 方法中组成文件地址,然后通过 Pandas 来读取 .csv 文件。

代码如下:

    @staticmethod
    def data_input(_dir, n):  # 输入数据,并用pandas读取csv文件

        _data = pd.read_csv(_dir + '\\_dataset\\' + n, low_memory=False)
            
        return _data

其实可以直接用相对地址进行读取 .csv 文件,而我在代码中使用了绝对地址。

然后将 Pandas 读取出来的数据转化为 list 格式,或者可以用 numpy 转化为 list

    location = data_io.data_input(_dir, n).iloc[:, [4, 3]].values.tolist()  # 数字代表着列数
    location = np.array(location)[:, [0, 1]].tolist()  # 数字代表着列数

最后便是生成地图了,代码如下:

    @staticmethod
    def map_g(_dir, location, n, name, color):  # 生成运行轨迹地图

        m = folium.Map([28, 115], zoom_start=10)  # 初始化坐标
        folium.PolyLine(
            location,  # 经纬度矩阵 [纬度、经度]
            weight=3,  # 划线粗细
            color=color,  # 划线颜色
            opacity=0.8  # 透明度
        ).add_to(m)  # 将线添加到地图上
        m.save(os.path.join(_dir + '\\map', n + name + '.html'))  # 将地图保存为 html 文件

注意 location 一定是 [纬度, 经度] 的列表 一张地图无法添加两条线(这也可能是我的问题)

今天有点晚了,下一次分享一下数据分析部分,而这也是整一个解题过程中的大头,耗时最多的部分。