最近比赛结果出来了,所以我打算对比赛做一个复盘,作日后参考之用。
我们的队伍有幸拿了全国二等奖,我在其中负责的是算法以及编程实现。
因为整个比赛时长只有七天,算法没有时间做特别多的优化,所以代码的质量可能不是特别高。
本人水平有限,若有缺漏之处欢迎指正。
研究问题
-
利用附件 1 所给数据,提取并分析车辆的运输路线以及其在运输过程中的速度、加速度等行车状态。提交附表中 10 辆车每辆车每条线路在经纬度坐标系下的运输线路图及对应的行车里程、平均行车速度、急加速急减速情况。
-
利用附件 1 所给数据,挖掘每辆运输车辆的不良驾驶行为,建立行车安全的评价模型,并给出评价结果。
-
综合考虑运输车辆的安全、效率和节能,并结合自然气象条件与道路状况等情况, 为运输车辆管理部门建立行车安全的综合评价指标体系与综合评价模型。
附表
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
车牌号 | AA00002 | AB00006 | AD00003 | AD00013 | AD00053 | AD00083 | AD00419 | AF00098 | AF00131 | AF00373 |
数据说明
- 附件 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 |
- 附件 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 | 采集日期 |
- 在车辆运输过程中,不良驾驶行为主要包括疲劳驾驶、急加速、急减速、怠速预热、超长怠速、熄火滑行、超速、急变道等。
数据类型样例
下面附上数据的样例截图:
开始解题
首先分析题目,题目中要完成的目标主要分为三块:
- 根据
.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
一定是 [纬度, 经度] 的列表 一张地图无法添加两条线(这也可能是我的问题)
今天有点晚了,下一次分享一下数据分析部分,而这也是整一个解题过程中的大头,耗时最多的部分。