【DCIC】数据分析学习:3.地图数据统计

目录

学习目标

地图数据统计(基础知识)

GPS经纬度

分组聚合统计

地图数据统计(实践)

统计巡游车与网约车分布

学习资源

任务


学习目标

  • GPS经纬度介绍
  • Pandas分组聚合
  • 出租车与网约车经纬度统计

地图数据统计(基础知识)

在任务三,我们希望通过分析和统计能够发现:

  • 巡游车与网约车的空间分布;
  • 上下客点分布密度:上下车位置分布;

GPS经纬度

  • WGS-84原始坐标系,一般用国际GPS记录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的;但是在国内是不允许直接用WGS84坐标系标注的,必须经过加密后才能使用;
  • GCJ-02坐标系,又名“火星坐标系”,是我国国测局独创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,可以说GCJ-02是国内最广泛使用的坐标系;
  • 百度坐标系BD-09,百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图;

地图坐标系转换方法:https://github.com/wandergis/coordTransform_py

分组聚合统计

对数据集进行分组并对各组应用一个函数(无论是聚合还是转换),通常是数据分析工作中的重要环节。在将数据集加载、融合、准备好之后,通常就是计算分组统计或生成透视表。pandas提供了一个灵活高效的gruopby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。

关系型数据库和SQL(Structured Query Language,结构化查询语言)能够如此流行的原因之一就是其能够方便地对数据进行连接、过滤、转换和聚合。但是,像SQL这样的查询语言所能执行的分组运算的种类很有限。

通过分组聚合统计,可以完成:

  • 使用一个或多个键(形式可以是函数、数组或DataFrame列名)分割pandas对象。
  • 计算分组的概述统计,比如数量、平均值或标准差,或是用户定义的函数。
  • 应用组内转换或其他运算,如规格化、线性回归、排名或选取子集等。
  • 计算透视表或交叉表。
  • 执行分位数分析以及其它统计分组分析。

Hadley Wickham(许多热门R语言包的作者)创造了一个用于表示分组运算的术语"split-apply-combine"(拆分-应用-合并)。

  • 第一个阶段,pandas对象(无论是Series、DataFrame还是其他的)中的数据会根据你所提供的一个或多个键被拆分(split)为多组。拆分操作是在对象的特定轴上执行的。例如,DataFrame可以在其行(axis=0)或列(axis=1)上进行分组。
  • 将一个函数应用(apply)到各个分组并产生一个新值。
  • 所有这些函数的执行结果会被合并(combine)到最终的结果对象中。结果对象的形式一般取决于数据上所执行的操作。下图大致说明了一个简单的分组聚合过程。

聚合指的是任何能够从数组产生标量值的数据转换过程,比如mean、count、min以及sum等。

地图数据统计(实践)

统计巡游车与网约车分布

下面代码以将以巡游车GPStaxiGps20190531.csv为案例进行数据统计:

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 = 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, drop=True)
taxigps2019.head()

  • 统计每辆巡游车最早、最晚出现的记录:
df_first = taxigps2019.groupby(['CARNO']).first()
 LATITUDELONGITUDEGPS_TIMEDRIVING_DIRECTIONGPS_SPEEDOPERATING_STATUS
CARNO      
0006d282be70d06881a7513b69fcaa6024.479755118.1469352019-05-31 01:31:202920.0000001
000e8886a7b27ca761e34d59b1dee35c24.550379118.1030122019-05-31 01:31:3814872.1875006
001df76bfa67259259f596c6dd353e6a24.499088118.1411822019-05-31 01:31:0927837.0000006
001e3756542dc796b402dfd1b56fd4ec24.471125118.1055602019-05-31 01:31:1434635.0937506
002b23a3762ea245f18cc896a55579d224.544592118.1024632019-05-31 01:31:211990.3000491
.....................
ffe9d9afeabd49c83ef8f7f5f09556cd24.526094118.1438522019-05-31 01:31:5000.0000001
ffea5e974b86b835b97eea1cd34fe3b824.479177118.1503142019-05-31 01:31:36140.0000001
ffedc235a5a3d891139a2d3ec2396b3e24.482244118.1164472019-05-31 01:31:24320.0000001
fff0bc740b883d541d098f5063e1f43f24.533218118.1395422019-05-31 01:32:01640.0000001
fff20f025f560278d601b2fd47e1f6b724.427284118.1338962019-05-31 01:31:2620856.8125001

6768 rows × 6 columns

df_last = taxigps2019.groupby(['CARNO']).last()
 LATITUDELONGITUDEGPS_TIMEDRIVING_DIRECTIONGPS_SPEEDOPERATING_STATUS
CARNO      
0006d282be70d06881a7513b69fcaa6024.498701118.0301822019-05-31 23:59:585444.4062501
000e8886a7b27ca761e34d59b1dee35c24.538876118.1298902019-05-31 23:59:492320.0000001
001df76bfa67259259f596c6dd353e6a24.488588118.1571962019-05-31 23:59:4725230.0937506
001e3756542dc796b402dfd1b56fd4ec24.524464118.1470952019-05-31 23:59:498012.8984386
002b23a3762ea245f18cc896a55579d224.497768118.1803742019-05-31 23:59:4500.0000001
.....................
ffe9d9afeabd49c83ef8f7f5f09556cd24.526243118.1457902019-05-31 23:59:222750.0000001
ffea5e974b86b835b97eea1cd34fe3b824.587500118.0181432019-05-31 23:59:193210.0000001
ffedc235a5a3d891139a2d3ec2396b3e24.497433118.1360092019-05-31 23:59:351550.0000001
fff0bc740b883d541d098f5063e1f43f24.533175118.1395192019-05-31 23:59:46610.0000001
fff20f025f560278d601b2fd47e1f6b724.457750118.0759892019-05-31 23:59:4933425.0937506

6768 rows × 6 columns

  • 统计每辆巡游车最早最晚的时间间隔:
df = df_last['GPS_TIME'] - df_first['GPS_TIME']
df = df.reset_index()

df['GPS_HOUR'] = df['GPS_TIME'].dt.seconds / 3600
df['GPS_HOUR'] = df['GPS_HOUR'].astype(int)
df.set_index('CARNO', inplace=True)
 GPS_TIMEGPS_HOUR
CARNO  
0006d282be70d06881a7513b69fcaa6022:28:3822
000e8886a7b27ca761e34d59b1dee35c22:28:1122
001df76bfa67259259f596c6dd353e6a22:28:3822
001e3756542dc796b402dfd1b56fd4ec22:28:3522
002b23a3762ea245f18cc896a55579d222:28:2422
.........
ffe9d9afeabd49c83ef8f7f5f09556cd22:27:3222
ffea5e974b86b835b97eea1cd34fe3b822:27:4322
ffedc235a5a3d891139a2d3ec2396b3e22:28:1122
fff0bc740b883d541d098f5063e1f43f22:27:4522
fff20f025f560278d601b2fd47e1f6b722:28:2322

6768 rows × 2 columns

  • 统计每辆巡游车的经纬度和速度极差:
taxigps2019 = taxigps2019[taxigps2019['LATITUDE'] != 0]
taxigps2019 = taxigps2019[taxigps2019['LONGITUDE'] != 0]

df['LATITUDE_PTP'] = taxigps2019.groupby(['CARNO'])['LATITUDE'].apply(np.ptp)
df['LONGITUDE_PTP'] = taxigps2019.groupby(['CARNO'])['LONGITUDE'].apply(np.ptp)
df['GPS_SPEED_PTP'] = taxigps2019.groupby(['CARNO'])['GPS_SPEED'].apply(np.ptp)

df['LATITUDE_PTP']
# CARNO
# 0006d282be70d06881a7513b69fcaa60    0.082424
# 000e8886a7b27ca761e34d59b1dee35c    0.218086
# 001df76bfa67259259f596c6dd353e6a    0.089241
# 001e3756542dc796b402dfd1b56fd4ec    0.208961
# 002b23a3762ea245f18cc896a55579d2    0.113722
#                                       ...   
# ffe9d9afeabd49c83ef8f7f5f09556cd    0.113094
# ffea5e974b86b835b97eea1cd34fe3b8    0.203405
# ffedc235a5a3d891139a2d3ec2396b3e    0.254045
# fff0bc740b883d541d098f5063e1f43f    0.102463
# fff20f025f560278d601b2fd47e1f6b7    0.188639
# Name: LATITUDE_PTP, Length: 6768, dtype: float64

df['LONGITUDE_PTP']
# CARNO
# 0006d282be70d06881a7513b69fcaa60    0.167244
# 000e8886a7b27ca761e34d59b1dee35c    0.228439
# 001df76bfa67259259f596c6dd353e6a    0.111763
# 001e3756542dc796b402dfd1b56fd4ec    0.176155
# 002b23a3762ea245f18cc896a55579d2    0.113892
#                                       ...   
# ffe9d9afeabd49c83ef8f7f5f09556cd    0.082634
# ffea5e974b86b835b97eea1cd34fe3b8    0.204063
# ffedc235a5a3d891139a2d3ec2396b3e    0.160561
# fff0bc740b883d541d098f5063e1f43f    0.118431
# fff20f025f560278d601b2fd47e1f6b7    0.170204
# Name: LONGITUDE_PTP, Length: 6768, dtype: float64

df['GPS_SPEED_PTP']
# CARNO
# 0006d282be70d06881a7513b69fcaa60     79.6250
# 000e8886a7b27ca761e34d59b1dee35c     90.6875
# 001df76bfa67259259f596c6dd353e6a     74.1250
# 001e3756542dc796b402dfd1b56fd4ec     98.1250
# 002b23a3762ea245f18cc896a55579d2     78.1250
#                                       ...   
# ffe9d9afeabd49c83ef8f7f5f09556cd     85.1250
# ffea5e974b86b835b97eea1cd34fe3b8     83.3125
# ffedc235a5a3d891139a2d3ec2396b3e     98.1250
# fff0bc740b883d541d098f5063e1f43f     87.0000
# fff20f025f560278d601b2fd47e1f6b7    100.6875
# Name: GPS_SPEED_PTP, Length: 6768, dtype: float64
  • 通过统计经纬度是不是全天都为0,我们可以剔除58辆全天GPS都异常的车。
  • 计算一下每辆巡游车的平均经纬度(每天运动的中心),并绘制热力度:
df['LONGITUDE_MEAN'] = taxigps2019.groupby(['CARNO'])['LONGITUDE'].mean()
df['LATITUDE_MEAN'] = taxigps2019.groupby(['CARNO'])['LATITUDE'].mean()
df = df.dropna()

df['LONGITUDE_MEAN']
# CARNO
# 0006d282be70d06881a7513b69fcaa60    118.136398
# 000e8886a7b27ca761e34d59b1dee35c    118.063110
# 001df76bfa67259259f596c6dd353e6a    118.132309
# 001e3756542dc796b402dfd1b56fd4ec    118.124062
# 002b23a3762ea245f18cc896a55579d2    118.137367
#                                        ...    
# ffe9d9afeabd49c83ef8f7f5f09556cd    118.147385
# ffea5e974b86b835b97eea1cd34fe3b8    118.064346
# ffedc235a5a3d891139a2d3ec2396b3e    118.120026
# fff0bc740b883d541d098f5063e1f43f    118.122116
# fff20f025f560278d601b2fd47e1f6b7    118.128235
# Name: LONGITUDE_MEAN, Length: 6764, dtype: float32

df['LATITUDE_MEAN']
# CARNO
# 0006d282be70d06881a7513b69fcaa60    24.498341
# 000e8886a7b27ca761e34d59b1dee35c    24.573448
# 001df76bfa67259259f596c6dd353e6a    24.480791
# 001e3756542dc796b402dfd1b56fd4ec    24.505524
# 002b23a3762ea245f18cc896a55579d2    24.490599
#                                       ...    
# ffe9d9afeabd49c83ef8f7f5f09556cd    24.519753
# ffea5e974b86b835b97eea1cd34fe3b8    24.537611
# ffedc235a5a3d891139a2d3ec2396b3e    24.519087
# fff0bc740b883d541d098f5063e1f43f    24.505892
# fff20f025f560278d601b2fd47e1f6b7    24.480259
# Name: LATITUDE_MEAN, Length: 6764, dtype: float32

学习资源

学习Pandas最好的教程是《利用 Python 进行数据分析》,这本书是Pandas作者撰写,非常适合大家进行学习。如何用Pandas实现的思路,如何实现的又快又好是需要积累经验的。

任务

  • 统计20190531出租车在LONGITUDE(118.155060±0.01)、LATITUDE(24.506035±0.01)方位内打车的平均等待时间。
taxiOrder = pd.read_csv(
    'data/taxiOrder20190531.csv', 
    dtype = {
        'GETON_LONGITUDE': np.float32,
        'GETON_LATITUDE': np.float32,
        'GETOFF_LONGITUDE': np.float32,
        'GETOFF_LATITUDE': np.float32,
        'PASS_MILE': np.float32,
        'NOPASS_MILE': np.float32,
        'WAITING_TIME': np.float32,
    }
)
taxiOrder = taxiOrder.rename(columns={'CAR_NO': 'CARNO'})
taxiOrder['GETON_DATE'] = pd.to_datetime(taxiOrder['GETON_DATE'])
taxiOrder['GETOFF_DATE'] = pd.to_datetime(taxiOrder['GETOFF_DATE'])
taxiOrder.sort_values(by=['CARNO', 'GETON_DATE'], inplace=True)
taxiOrder.reset_index(inplace=True, drop=True)

df = taxiOrder.loc[
    (taxiOrder['GETON_LONGITUDE'] > (118.155060 - 0.01)) & 
    (taxiOrder['GETON_LONGITUDE'] < (118.155060 + 0.01)) &
    (taxiOrder['GETON_LATITUDE'] > (24.506035 - 0.01)) &
    (taxiOrder['GETON_LATITUDE'] < (24.506035 + 0.01))
]

df['WAITING_TIME'].mean()
# 276.4931945800781
  • 统计20190531 - 20190609 期间出租订单经纬度上平均等待时间长的位置(且位置出现评率大于5)。
taxiOrder = []
filenames = [
    'data/taxiOrder20190531.csv', 'data/taxiOrder20190601.csv', 'data/taxiOrder20190602.csv',
    'data/taxiOrder20190603.csv', 'data/taxiOrder20190604.csv', 'data/taxiOrder20190605.csv',
    'data/taxiOrder20190606.csv', 'data/taxiOrder20190607.csv', 'data/taxiOrder20190608.csv',
    'data/taxiOrder20190609.csv'
]
for filename in filenames:
    taxiOrder.append(
        pd.read_csv(
            filename, 
            dtype = {
                'GETON_LONGITUDE': np.float32,
                'GETON_LATITUDE': np.float32,
                'GETOFF_LONGITUDE': np.float32,
                'GETOFF_LATITUDE': np.float32,
                'PASS_MILE': np.float32,
                'NOPASS_MILE': np.float32,
                'WAITING_TIME': np.float32,
            })
    )
taxiOrder = pd.concat(taxiOrder, ignore_index=True)

se_time = taxiOrder.groupby(['GETON_LONGITUDE', 'GETON_LATITUDE'])['WAITING_TIME'].mean().sort_values(ascending=False)
se = taxiOrder.groupby(['GETON_LONGITUDE', 'GETON_LATITUDE']).count()['CAR_NO'].sort_values(ascending=False)

for i, j in enumerate(se_time.index):
    if se[j] > 5:
        print(j, se[j], se_time[j])
        break

# (118.16363525390625, 24.511585235595703) 6 32906.0
  • 对比2019年和2020年出租车端午节订单的平均等待时间,是如何变化的(上升、下降还是不变)?
taxiOrder_2019 = []
taxiOrder_2020 = []
filenames_2019 = [
    'data/taxiOrder20190607.csv', 'data/taxiOrder20190608.csv', 'data/taxiOrder20190609.csv'
]
filenames_2020 = [
    'data/taxiOrder20200625.csv', 'data/taxiOrder20200626.csv', 'data/taxiOrder20200627.csv',
]

for filename in filenames_2019:
    taxiOrder_2019.append(
        pd.read_csv(
            filename, 
            dtype = {
                'GETON_LONGITUDE': np.float32,
                'GETON_LATITUDE': np.float32,
                'GETOFF_LONGITUDE': np.float32,
                'GETOFF_LATITUDE': np.float32,
                'PASS_MILE': np.float32,
                'NOPASS_MILE': np.float32,
                'WAITING_TIME': np.float32,
            })
    )
taxiOrder_2019 = pd.concat(taxiOrder_2019, ignore_index=True)

for filename in filenames_2020:
    taxiOrder_2020.append(
        pd.read_csv(
            filename, 
            dtype = {
                'GETON_LONGITUDE': np.float32,
                'GETON_LATITUDE': np.float32,
                'GETOFF_LONGITUDE': np.float32,
                'GETOFF_LATITUDE': np.float32,
                'PASS_MILE': np.float32,
                'NOPASS_MILE': np.float32,
                'WAITING_TIME': np.float32,
            })
    )
taxiOrder_2020 = pd.concat(taxiOrder_2020, ignore_index=True)

taxiOrder_2019['WAITING_TIME'].mean()
# 243.95602416992188

taxiOrder_2020['WAITING_TIME'].mean()
# 215.83151245117188

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值