任务1:数据读取


## 学习目标

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

## 前置任务答疑

在任务0打卡任务中,我们发现同学们暂时遇到以下问题:

  • 数据集过大,电脑费劲:本节课我们将会给出的具体的操作方法,基本上4G内存电脑都可以完成;
  • 对空间数据的分析和可视化从未涉足:在后续任务会给出可视化方法介绍;
  • 数据需要自己整合一下吗?还有有很多条是不运行的,速度为0:如果机器内存大可以整合,也可以分天分析;速度为0有可能的是瞬时速度;
  • 登录时绑定手机收不到验证码:收不到验证码的同学,请加QQ:3462287298;

## 赛题任务

需要注意本次学习使用的数据为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城市巡游车订单数据
网约车订单数据 wycOrder20200606-20200609.zip 2020年端午假期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

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

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

#### 读取代码

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

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

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

  1. 巡游车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()
OPERATING_STATUS GPS_SPEED DRIVING_DIRECTION LONGITUDE LATITUDE
count 100000.000000 100000.000000 100000.000000 100000.000000 100000.000000
mean 2.415830 15.922179 161.451510 117.388134 24.354396
std 2.320472 22.837529 113.725946 9.273066 1.932351
min 1.000000 0.000000 0.000000 0.000000 0.000000
25% 1.000000 0.000000 59.000000 118.100982 24.480172
50% 1.000000 0.000000 167.000000 118.123175 24.493398
75% 6.000000 28.900000 261.000000 118.149498 24.516875
max 8.000000 381.300000 360.000000 129.110960 34.656481
  • 通过info()函数完成表格信息展示;
taxigps2019.info()
    
    RangeIndex: 100000 entries, 0 to 99999
    Data columns (total 7 columns):
    OPERATING_STATUS     100000 non-null int64
    GPS_SPEED            100000 non-null float64
    DRIVING_DIRECTION    100000 non-null int64
    GPS_TIME             100000 non-null object
    LONGITUDE            100000 non-null float64
    LATITUDE             100000 non-null float64
    CARNO                100000 non-null object
    dtypes: float64(3), int64(2), object(2)
    memory usage: 5.3+ MB

通过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()
    
    RangeIndex: 100000 entries, 0 to 99999
    Data columns (total 7 columns):
    OPERATING_STATUS     100000 non-null uint8
    GPS_SPEED            100000 non-null float16
    DRIVING_DIRECTION    100000 non-null uint16
    GPS_TIME             100000 non-null object
    LONGITUDE            100000 non-null float32
    LATITUDE             100000 non-null float32
    CARNO                100000 non-null object
    dtypes: float16(1), float32(2), object(2), uint16(1), uint8(1)
    memory usage: 2.8+ MB

为了方便查看数据,我们还可以对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['GPS_TIME'] = pd.to_datetime(taxigps2019['GPS_TIME'])
taxigps2019.sort_values(by=['CARNO','GPS_TIME'], inplace=True)
taxigps2019.reset_index(inplace=True)
  1. 巡游车订单读取

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

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)

  1. 网约车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)
  1. 网约车订单数据读取
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数据(2019年、2020年);
  • 巡游车订单数据(2019年、2020年);
  • 网约车GPS数据(2019年、2020年);
  • 网约车订单数据(2019年、2020年);

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

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

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

## 学习资源


## 课堂任务

  1. 如何统计某个出租车的在一天的有效运行时间?
  2. 如何统计某个出租车的行驶距离?
  3. 如何找到数据中的异常值?

## 打卡任务

  1. 统计巡游车GPS数据在20190603中包含多少辆出租车🚖?
  2. 统计网约车GPS数据在20190603中包含多少辆网约车🚗?
  3. 统计巡游车订单数据在20190603中上车经纬度的最大最小值?
  4. 统计网约车订单数据集在20190603中下车经纬度最常见的位置?
    • 假设经度+维度,各保留三维有效数字组合得到具体位置
    • 小提示:可以将经纬度拼接到一起进行统计


© 2019-2023 coggle.club 版权所有     京ICP备20022947    京公网安备 11030102010643号