目录

学习目标

赛题任务

赛题介绍

赛题思路

赛题数据

数据说明

数据读取

Pandas

Numpy

读取代码

数据统计

任务


学习目标

  • 下载好数据集,并理解赛题具体的背景;
  • 理解并梳理清楚赛题的任务;
  • 完成赛题数据读取;

赛题任务

需要注意本次学习使用的数据为DCIC赛题2数据,需要报名后才能下载。报名规则及报名手册具体详见[赛程赛规]-[参赛团队]

赛题介绍

  • 赛题名称:A城市巡游车与网约车运营特征对比分析
  • 赛题说明:出租车作为城市客运交通系统的重要组成部分,以高效、便捷、灵活等优点深受居民青睐。出租车每天的运营中会产生大量的上下车点位相关信息,对这些数据进行科学合理的关联和挖掘,对比在工作日以及休息日、节假日的出租车数据的空间分布及其动态变化,对出租车候车泊位、管理调度和居民通勤特征的研究具有重要意义。
    • 出租车/网约车:上下车地点挖掘;
    • 出租车/网约车:不同日期的空间变化;
    • 出租车/网约车:泊车和调度问题;
  • 赛题任务:参赛者需依据赛事方提供的出租车(包括巡游车和网约车)GPS和订单数据
    • 综合应用统计分析方法分别对所提供的巡游车和网约车运营的时间、空间分布特征进行量化计算,包括计算2年的每年工作日取日平均,非工作日取日平均和节假日取日平均,三种类型各自平均的时变分布变化,三种时间类型按网格划分的平均空间分布(网格划分颗粒度选手自选),并分别对比分析所提供的网约车、巡游车,计算2年每年按工作日取日平均,非工作日取日平均和节假日取日平均三种类型的日均空驶率、订单平均运距、订单平均运行时长、上下客点分布密度等时变特性;
    • 根据巡游车和网约车的时空运营特征,并尝试对巡游车与网约车的融合发展提出相关建议。在分析过程,参赛者必须用到但不局限于提供的数据,可自行加入自有数据进行参赛,但需说明自带数据来源并保证数据合法合规使用。

赛题思路

通过赛题理解&数据分析,参赛选手需要回答上述问题:

  • 每年工作日取日平均,非工作日取日平均和节假日取日平均,三种情况下出租车&网约车:
    • 运营时间规律:出车时间和运行时间;
    • 空间分布规律:城市分布规律,订单分布规律;
    • 日均空驶率:空驶里程(没有载客)在车辆总运行里程中所占的比例;
    • 订单平均运距:订单平均距离计算;
    • 订单平均运行时长:订单平时时长计算;
    • 上下客点分布密度:上下车位置分布;
  • 对出租车&网约车的调度、融合发展提出建议:
    • 如何进行订单调度?识别打不到车的位置;
    • 如何进行停车场推荐?
    • 订单差异性分析?

赛题数据

赛题数据下载页面,需要注册后下载。

数据说明

  • 2019年端午节:2019-6-07(7、8、9假期)
  • 2020年端午节:2020-6-25(25、26、27假期)
文件类型 文件名 文件说明
巡游车GPS数据 taxiGps20190531.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190601.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190602.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190603.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190604.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190605.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190606.zip 2019年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190607.zip 2019年端午假期A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190608.zip 2019年端午假期A城市巡游车GPS数据
巡游车GPS数据 taxiGps20190609.zip 2019年端午假期A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200618.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200619.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200620.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200621.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200622.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200623.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200624.zip 2020年端午前一周A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200625.zip 2020年端午假期A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200626.zip 2020年端午假期A城市巡游车GPS数据
巡游车GPS数据 taxiGps20200627.zip 2020年端午假期A城市巡游车GPS数据
巡游车订单数据 taxiOrder20190531-20190605.zip 2019年端午前一周A城市巡游车订单数据
巡游车订单数据 taxiOrder20190606-20190609.zip 2019年端午假期A城市巡游车订单数据
巡游车订单数据 taxiOrder20200618-20200623.zip 2020年端午前一周A城市巡游车订单数据
巡游车订单数据 taxiOrder20200624-20200627.zip 2020年端午假期A城市巡游车订单数据
网约车GPS数据 wycGps20190531-20190603.zip 2019年端午前一周A城市网约车GPS数据
网约车GPS数据 wycGps20190604-20190605.zip 2019年端午前一周A城市网约车GPS数据
网约车GPS数据 wycGps20190606-20190607.zip 2019年端午假期A城市网约车GPS数据
网约车GPS数据 wycGps20190608-20190609.zip 2019年端午假期A城市网约车GPS数据
网约车GPS数据 wycGps20200618-20200619.zip 2020年端午前一周A城市网约车GPS数据
网约车GPS数据 wycGps20200620-20200622.zip 2020年端午前一周A城市网约车GPS数据
网约车GPS数据 wycGps20200623.zip 2020年端午前一周A城市网约车GPS数据
网约车GPS数据 wycGps20200624-20200627.zip 2020年端午假期A城市网约车GPS数据
网约车订单数据 taxiOrder20190531-20190605.zip 2019年端午前一周A城市巡游车订单数据
网约车订单数据 wycOrder20190606-20190609.zip 2019年端午假期A城市网约车订单数据
网约车订单数据 wycOrder20200618-20200622.zip 2020年端午前一周A城市巡游车订单数据
网约车订单数据 wycOrder20200623-20200627.zip 2020年端午假期A城市网约车订单数据
路网矢量数据   某市路网矢量数据

比赛详细数据说明:https://data.xm.gov.cn/opendata-competition/#/contest_explain

赛题数据基本可以分为四类:

  • 巡游车GPS数据(2019年、2020年);
  • 巡游车订单数据(2019年、2020年);
  • 网约车GPS数据(2019年、2020年);
  • 网约车订单数据(2019年、2020年);

数据读取

在进行数据读取的过程中,并不需要把所有的数据都读取,可以分别读取单个文件完成数据分析,因为数据都是按照时间进行划分的。比如我们先完成巡游车taxiGps20190531.csv数据分析,进而可以直接将分析逻辑应用到taxiGps20190601.csv文件中。

Pandas

Python环境下读取结构化数据,并对结构化数据进行统计的最好的库是Pandas。在Pandas中表格是使用DataFrame进行存储和展示的,其参考了R语言中的DataFrame格式。

结构化数据又称为表格数据,与非结构化数据(文本、图像、音频和视频)区分明显。在表格中每行代表的一条记录(样本),一列表示一个字段(特征)。

优点1:Pandas封装了众多的文本读取方式,从文本文件到json文件,Pandas都可以简单的进行读取为DataFrame,非常方便;

优点2:Pandas可以无缝进行可视化,直接通过调用函数就可以完成可视化绘图;

优点3:Pandas可以很方便的完成数据索引、聚合和计算的操作;

Numpy

Pandas环境下完成科学计算一定会用到NumpyNumpy是科学计算的基础库。

  • Numpy提供了矩阵存储、计算的快速实现;
  • Numpy是现有机器学习、深度学习库基础的数据格式;
  • Numpy是数据科学(数据存储、数据处理和数据可视化)的基础格式;

读取代码

由于赛题给定的数据集文件都比较大,文件行数都比较多,如果完全进行读取可会让电脑卡死,内存爆炸;

  • 可以只读取部分文件,读取单个文件完成数据分析;
  • 修改字段类型节约空间;

接下来我们将给出单个文件和部分文件的读取方法,供大家参考。

巡游车GPS数据读取

在读取数据时,可以完成以下操作:

  • 通过read_csv函数输入路径和nrows设置读取的文件行数;
  • nrows可以取值为数值或者None,前者数值控制行数,后者读取所有(默认是读取所有);
  • 读取完成后的数据为DataFrame形式,可以通过describe()函数完成描述型分析统计;

建议大家先设置nrows完成读取,不要直接读取所有文件;

import pandas as pd
import numpy as np

# 文件目录,相对路径
INPUT_PATH = '../input/'

# 文件读取行数
MAX_ROWS = 100000 

taxigps2019 = pd.read_csv(INPUT_PATH + 'taxiGps20190531.csv', nrows=MAX_ROWS)
taxigps2019.describe()

  • 通过info()函数完成表格信息展示;
taxigps2019.info()

通过describe()info()函数,我们可以初步得到现有的字段的取值,10w条数据占用5MB内存。我们也可以完成数据字段压缩的操作,将字段类型根据取值空间进行修改,压缩内存使用需求。

import pandas as pd
import numpy as np

INPUT_PATH = '../input/' #文件目录
MAX_ROWS = 100000 # 文件读取行数

taxigps2019 = pd.read_csv(INPUT_PATH + 'taxiGps20190531.csv', nrows=MAX_ROWS,
                         dtype = {
                             'DRIVING_DIRECTION': np.uint16,
                             'OPERATING_STATUS': np.uint8,
                             'LONGITUDE': np.float32,
                             'LATITUDE': np.float32,
                             'GPS_SPEED': np.float16 
                         })

taxigps2019.info()

为了方便查看数据,我们还可以对GPS数据进行排序,这样就完成了单个文件的读取。

taxigps2019 = taxigps2019[taxigps2019.columns[::-1]]
taxigps2019.sort_values(by=['CARNO','GPS_TIME'], inplace=True)
taxigps2019.reset_index(inplace=True, drop=True)
taxigps2019.head()

多个文件(多天)可以直接将文件进行拼接即可:

# 出租车2019年GPS
taxigps2019 = pd.concat([
    pd.read_csv(INPUT_PATH + 'taxiGps20190531.csv', nrows=MAX_ROWS,
                         dtype = {
                             'DRIVING_DIRECTION': np.uint16,
                             'OPERATING_STATUS': np.uint8,
                             'LONGITUDE': np.float32,
                             'LATITUDE': np.float32,
                             'GPS_SPEED': np.float16 
                         }),
    pd.read_csv(INPUT_PATH + 'taxiGps20190601.csv', nrows=MAX_ROWS,
                         dtype = {
                             'DRIVING_DIRECTION': np.uint16,
                             'OPERATING_STATUS': np.uint8,
                             'LONGITUDE': np.float32,
                             'LATITUDE': np.float32,
                             'GPS_SPEED': np.float16 
                         })
])
taxigps2019 = taxigps2019[taxigps2019.columns[::-1]]
taxigps2019.sort_values(by=['CARNO','GPS_TIME'], inplace=True)
taxigps2019.reset_index(inplace=True)

巡游车订单读取

巡游车订单数据单个文件读取:

taxiorder2019 = pd.read_csv(INPUT_PATH + 'taxiOrder20190531.csv', nrows=MAX_ROWS,
                           dtype = {
                               'GETON_LONGITUDE': np.float32,
                               'GETON_LATITUDE': np.float32,
                               'GETOFF_LONGITUDE': np.float32,
                               'GETOFF_LATITUDE': np.float32,
                               'PASS_MILE': np.float16,
                               'NOPASS_MILE': np.float16,
                               'WAITING_TIME': np.float16
                           })

taxiorder2019 = taxiorder2019.rename(columns={'CAR_NO':'CARNO'})
taxiorder2019.sort_values(by=['CARNO','GETON_DATE'], inplace=True)
taxiorder2019.reset_index(inplace=True, drop=True)

巡游车订单数据多个文件读取:

taxiorder2019 = pd.concat([
    pd.read_csv(INPUT_PATH + 'taxiOrder20190531.csv', nrows=MAX_ROWS,
                           dtype = {
                               'GETON_LONGITUDE': np.float32,
                               'GETON_LATITUDE': np.float32,
                               'GETOFF_LONGITUDE': np.float32,
                               'GETOFF_LATITUDE': np.float32,
                               'PASS_MILE': np.float16,
                               'NOPASS_MILE': np.float16,
                               'WAITING_TIME': np.float16
                           }),
    pd.read_csv(INPUT_PATH + 'taxiOrder20190601.csv', nrows=MAX_ROWS,
                           dtype = {
                               'GETON_LONGITUDE': np.float32,
                               'GETON_LATITUDE': np.float32,
                               'GETOFF_LONGITUDE': np.float32,
                               'GETOFF_LATITUDE': np.float32,
                               'PASS_MILE': np.float16,
                               'NOPASS_MILE': np.float16,
                               'WAITING_TIME': np.float16
                           })
taxiorder2019 = taxiorder2019.rename(columns={'CAR_NO':'CARNO'})
taxiorder2019.sort_values(by=['CARNO','GETON_DATE'], inplace=True)
taxiorder2019.reset_index(inplace=True, drop=True)
])

网约车GPS数据读取

wycgps2019 = pd.read_csv(INPUT_PATH + 'wycGps20190531.csv', nrows=MAX_ROWS,
                        dtype={
                            'LONGITUDE': np.float32,
                            'LATITUDE': np.float32,
                            'SPEED': np.float16
                        })

wycgps2019 = wycgps2019.rename(columns={'CAR_NO':'CARNO'})
wycgps2019 = wycgps2019[wycgps2019.columns[::-1]]
wycgps2019.sort_values(by=['CARNO','POSITION_TIME'], inplace=True)

wycgps2019['BIZ_STATUS'] = wycgps2019['BIZ_STATUS'].fillna(-1).astype(np.int8)
wycgps2019['ENCRYPT'] = wycgps2019['ENCRYPT'].fillna(-1).astype(np.int8)

网约车订单数据读取

wycorder2019 = pd.read_csv(INPUT_PATH + 'wycOrder20190531.csv', nrows=MAX_ROWS,
                        dtype={
                            'DEP_LONGITUDE': np.float32,
                            'DEP_LATITUDE': np.float32,
                            'DEST_LONGITUDE': np.float32,
                            'DEST_LATITUDE': np.float32,
                        })
wycorder2019 = wycorder2019.rename(columns={'CAR_NO':'CARNO'})
wycorder2019.sort_values(by=['CARNO','DEP_TIME'], inplace=True)

数据统计

赛题数据基本可以分为四类,不同类型的赛题数据在字段格式上有一定差异:

  • 巡游车GPS数据(2019年、2020年);
  • 巡游车订单数据(2019年、2020年);
  • 网约车GPS数据(2019年、2020年);
  • 网约车订单数据(2019年、2020年);

为了方便大家学习,接下来我们将以巡游车GPStaxiGps20190531.csv为案例进行数据统计:

  • 有多少辆出租车:
taxigps2019['CARNO'].nunique()
  • 出租车平均GPS速度:
np.clip(taxigps2019['GPS_SPEED'].values, 0, 150).mean()
  • 出租车运营状态统计:
taxigps2019['OPERATING_STATUS'].value_counts()
  • 某辆巡游车数据:
taxigps2019[taxigps2019['CARNO'] == '0006d282be70d06881a7513b69fcaa60']
  • 某个运行方向的车辆统计:
taxigps2019[taxigps2019['DRIVING_DIRECTION'] == 10]['CARNO'].unique()
  • 统计记录最多的GPS小时:
taxigps2019['GPS_TIME'] = pd.to_datetime(taxigps2019['GPS_TIME'])
taxigps2019['GPS_TIME'].dt.hour.value_counts()

通过数据读取和数据统计,我们可以很直接的对数据原始的形态进行检查,获取一手的资料。需要注意的是,此步骤是需要阅读比赛数据说明。赛题数据本身不规整,这是赛题的任务。

因此完成赛题任务的步骤如下:

  • 完成赛题的读取,理解赛题字段;
  • 理解赛题字段含义,并完成统计;
  • 将赛题要求,抽象为具体的统计逻辑;
  • 完成具体统计,并进行可视化和总结;

任务

  • 统计巡游车GPS数据在20190603中包含多少辆出租车?
taxiGps.CARNO.nunique()    # 6727
  • 统计网约车GPS数据在20190603中包含多少辆网约车?
wycGps.CARNO.nunique()    # 28774
  • 巡游车订单数据在20190603中上车【经度】的最小值?
taxiOrder.loc[taxiOrder.GETON_LONGITUDE != 0.0].GETON_LONGITUDE.sort_values()[:1]    # 35.695534
  • 巡游车订单数据在20190603中上车【维度】的最大值?
taxiOrder.loc[taxiOrder.GETON_LATITUDE != 0.0].GETON_LATITUDE.sort_values(ascending=False)[:1]    # 33.497204
  • 网约车订单数据集在20190603中下车经纬度最常见的位置?

dest = wycOrder.loc[:, ['DEST_LONGITUDE', 'DEST_LATITUDE']].applymap(lambda x: f'{x:.3f}')
dest['DEST'] = dest.DEST_LONGITUDE + dest.DEST_LATITUDE
dest.DEST.value_counts()    # 118.07524.635    4879

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐