使用Python分析纽约出租车搭乘数据

在纽约,出租车分为两类:黄色和绿色。黄色出租(Yellow TAXI)车可以在纽约五大区(布朗克斯区、布鲁克林区、曼哈顿、皇后区、斯塔滕岛)内任何地点搭载乘客。绿色出租车(Green TAXI)则被规定只允许在上曼哈顿、布朗克斯区、皇后区和斯塔滕岛接客,这两类出租车均由私人公司经营并受到纽约市出租车和轿车委员会(NYC Taxi and Limousine Commission)的监管。本篇文章使用python对绿色出租车2016年1月——6月的数据进行分析,探究绿色出租车的是使用趋势,用户使用习惯以及天气因素对出租车使用量的影响。

29201715966_43f2365b9f_b
开始前的准备工作

开始分析之前先进行导入库文件和数据的准备工作,首先导入分析过程中需要使用的库文件,用于对数据进行计算和格式转换,这里不再赘述,请见下面的代码。

#导入所需的库文件
import numpy as np
import pandas as pd
import time,datetime
import matplotlib.pyplot as plt

然后分别导入green_taxi 2016年1月至6月的数据表,并对数据表进行进行拼接。组成用于分析的完整数据大表。

#导入green_taxi2016年1-6月数据
green_taxi1=pd.DataFrame(pd.read_csv('green_tripdata_2016-01.csv'))
green_taxi2=pd.DataFrame(pd.read_csv('green_tripdata_2016-02.csv'))
green_taxi3=pd.DataFrame(pd.read_csv('green_tripdata_2016-03.csv'))
green_taxi4=pd.DataFrame(pd.read_csv('green_tripdata_2016-04.csv'))
green_taxi5=pd.DataFrame(pd.read_csv('green_tripdata_2016-05.csv'))
green_taxi6=pd.DataFrame(pd.read_csv('green_tripdata_2016-06.csv'))
#合并绿色出租车2016年1-6月数据
green_taxi=green_taxi1.append(green_taxi2,ignore_index=False)
green_taxi=green_taxi.append(green_taxi3,ignore_index=False)
green_taxi=green_taxi.append(green_taxi4,ignore_index=False)
green_taxi=green_taxi.append(green_taxi5,ignore_index=False)
green_taxi=green_taxi.append(green_taxi6,ignore_index=False)

通过查看维度,拼接完的数据大表共有901万条数据,20个字段。

#查看数据表维度
green_taxi.shape
(9018030, 20)

使用columns函数查看数据表中20个字段的列名称。通过字段名称可以发现,这张数据表中包括很多信息,包括乘客上下车时间,和经纬度信息,乘客数量,付款方式以及行驶距离和费率等等。

#查看数据表列名称
green_taxi.columns
Index(['VendorID', 'Lpep_dropoff_datetime', 'Store_and_fwd_flag', 'RateCodeID',
'Pickup_longitude', 'Pickup_latitude', 'Dropoff_longitude',
'Dropoff_latitude', 'Passenger_count', 'Trip_distance', 'Fare_amount',
'Extra', 'MTA_tax', 'Tip_amount', 'Tolls_amount', 'Ehail_fee',
'improvement_surcharge', 'Total_amount', 'Payment_type', 'Trip_type '],
dtype='object')

再查看一下数据表中的内容,使用head函数查看数据表前5行的具体内容。可以发现上下车时间既包括了日期信息也包括了具体的小时信息。付款方式则是以类别编码进行的标识。

#查看数据表前5行
green_taxi.head()

green_taxi_head

这里需要从NYC Taxi & Limousine Commission网站上下载一个对照文档将字符标识还原为类别名称。这个在后面会用到,下面是文档中的截图。

Payment_type
准备工作完成后,开始对Green TAXI的数据开始进行分析。

2016年1-6月使用趋势

这是一张实时Green TAXI的位置分布图。Green TAXI可以从曼哈顿北部(西110街和东96街的北部),布朗克斯,皇后区(不包括机场),布鲁克林和史坦顿岛的街道上接载乘客,并且可以在任何地方落客。每辆Green TAXI出租车也都可以在曼哈顿北部,布朗克斯,皇后区,布鲁克林和史坦顿岛和机场进行预约载客。我们先来看下2016年1-6月的整体使用趋势。

map

我们对Green TAXI中的数据进行处理,获得按月的使用量变化趋势。首先将数据表中的载客时间字段转化为日期格式,然后把这个字段设置为数据表的索引字段。并按月的维度对数据表中的数据进行汇总计数。并提取VendorID列作为每月Green TAXI的载客数量。

#将载客时间字段更改为时间格式
green_taxi['lpep_pickup_datetime']=pd.to_datetime(green_taxi['lpep_pickup_datetime'])
#将载客时间字段设置为数据表的索引字段
green_taxi = green_taxi.set_index('lpep_pickup_datetime')
#按月对数据表中的数据进行汇总计数
monthly=green_taxi.resample('M',how=len)['VendorID']

将按月的Green TAXI数据绘制为柱状图,来查看整体的变化趋势情况,下面是绘制趋势图的代码和结果。

#绘制分月载客数量变化趋势图
plt.rc('font', family='STXihei', size=15)
a=np.array([1,2,3,4,5,6])
plt.bar([1,2,3,4,5,6],monthly,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('月份')
plt.ylabel('搭乘次数')
plt.title('2016年1-6月Green TAXI搭乘次数')
plt.legend(['搭乘次数'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.6)
plt.xticks(a,('1月','2月','3月','4月','5月','6月'))
plt.ylim(0,1800000)
plt.show()

2016年1-6月Green TAXI搭乘次数

从图表来看,1月2月和6月的使用量相对较低,3月到5月使用量相对较高。这样的趋势与季节和温度有关系吗?纽约冬天一般从11月到次年3月,冷且风大。出租车的使用量是否和气温有关呢?我们这里先做一个假设,在文章的最后再来分析。

乘客数量分布

Green TAXI 的车型分为四种,根据用途和载客数量不同从小到大分布为Sedan,Town car,Minivan和SUV。下面我们来看下搭乘Green TAXI的乘客数量分布。换句话说就是每次搭乘时出租车内的人数。这里需要说明的是这个数字的采集方式是由出租车驾驶员手动输入的。因此可能会有一些不准确性。
eltaxistanews_taxi-en-edificio-de-TLC
要获得每次搭乘出租车乘客的分布情况,需要对数据表进行处理。我们首先查看下搭乘人数的范围,查看Passenger_count的最大值和最小值,范围是0-9个人。这里就可以看出问题。首先0人搭乘这个明显是有问题的。莫非是约车的时候打表来接的,然后又取消了订单?其次9个人乘坐出租车这个应该是SUV车型,应该是包含儿童或未成年人。否则即使是7座的SUV也很难坐下9个成年人。

#查看每次载客的乘客数量范围
green_taxi['Passenger_count'].min(),green_taxi['Passenger_count'].max()
(0, 9)

得到乘客数量范围后,我们对数据表按Passenger_count字段进行汇总计数,并绘制乘客人数分布图。

#按乘客数量对数据进行计数汇总
Passenger=green_taxi.groupby('Passenger_count')['Passenger_count'].agg(len)

下面是绘制乘客人数分布图的代码。

#绘制每次搭载乘客人数分布图
plt.rc('font', family='STXihei', size=15)
a=np.array([0,1,2,3,4,5,6,7,8,9])
plt.bar([0,1,2,3,4,5,6,7,8,9],Passenger,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('乘客数量')
plt.ylabel('搭乘次数')
plt.title('每次搭乘Green TAXI的乘客人数分布')
plt.legend(['人数'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('0人','1人','2人','3人','4人', '5人','6人','7人','8人','9人'))
plt.ylim(0,9000000)
plt.show()

每次搭乘Green TAXI的乘客人数分布
从乘客数量的分布情况来看,独自1人搭乘出租车的数量最多,其次为2人,5人,3人和6人。这里也有可能是出租车司机输入时的固定选择造成的。现有的数据中没有可以进行交叉验证的数据,因此这个乘客人数分布数据仅供参考。

支付方式分布

Green TAXI数据表中对乘客支付车费的方式分为了6类,通过对应文档分别为Credit card,
Cash,No charge,Dispute,Unknown,Voided trip。但仔细看会发现,这并不是6种不同的支付方式。如后面的免费,争议和空驶。甚至还出现了Unknown的情况。不过我们还是按
Payment_type字段对数据进行了汇总统计。下面是支付方式的统计代码和结果。

payleven_taxi
首先将支付方式的编号还原为具体的类别名称。下面是具体的代码。
#对数据表中的支付方式进行标注

bins = [0, 1, 2, 3, 4, 5, 6]
group_payment = ['Credit card', ' Cash', ' No charge', 'Dispute', 'Unknown', ' Voided trip']
green_taxi['group_payment'] = pd.cut(green_taxi['Payment_type'], bins, labels=group_payment)

然后按支付方式的名称字段对数据表进行计数汇总。

#按支付方式对数据表中的数据进行汇总计数
payment_type=green_taxi.groupby('group_payment')['group_payment'].agg(len)

对汇总后的支付方式数据汇总图表进行分析。

#绘制乘客支付方式分布图
plt.rc('font', family='STXihei', size=15)
a=np.array([1,2,3,4,5,6])
plt.bar([1,2,3,4,5,6],payment_type,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('支付方式')
plt.ylabel('搭乘次数')
plt.title('搭乘Green TAXI的支付方式')
plt.legend(['搭乘次数'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('Credit card','Cash','No charge','Dispute', 'Unknown','Voided trip'))
plt.show()

搭乘Green TAXI的支付方式
在所有的支付方式中,现金和信用卡是乘客使用最多的支付方式。其他的情况都很少见。其实本来几个类别就不是支付方式的分类。

平均距离及里程分布

Green TAXI起步价2.5美元(0.2英里以内),之后每0.2英里(约320米)或者等候2分钟加收40美分。从晚间8点到早上6点期间,加收夜行附加费0.50美元。高峰时刻(周一到周五下午4点到8点)附加费1美元。此外,乘客还需承担乘车期间产生的任何费用并另付小费(15%以上)。这里搭乘距离是影响金额的主要因素,我们来看下乘客在搭乘出租车时的距离分布情况。

QQ截图20161214165712

首先来看下乘客搭乘出租车的距离范围,查看Trip_distance的最大值和最小值。最短距离为0,最大距离为832.2英里。这里的0英里不知道是什么情况。

#查看乘客搭载距离范围
green_taxi['Trip_distance'].min(),green_taxi['Trip_distance'].max()
(0.0, 832.2)

用总的搭乘里程除以乘客搭乘次数计算出每次搭乘的平均行驶距离为2.81英里。

#计算每位乘客平均搭载的距离
green_taxi['Trip_distance'].sum()/green_taxi['Trip_distance'].count()
2.8170580049080391

对乘客搭乘距离进行分组,以5公里为一组进行划分。

#对乘客搭载距离进行分组
bins = [0, 5, 10, 50, 100, 200, 840]
group_distance = ['0-5公里', '5-10公里', '10-50公里', '50-100公里', '100-200公里', '200公里以上']
green_taxi['group_distance'] = pd.cut(green_taxi['Trip_distance'], bins, labels=group_distance)

按划分后的距离分组字段对数据表进行计数汇总,查看乘客搭乘的距离分布情况。

#按分组距离对数据表进行计数汇总
group_trip_distance=green_taxi.groupby('group_distance')['Trip_distance'].agg(len)

将乘客搭乘的距离分布数据绘制成图表。

#绘制乘客搭乘距离分布图
plt.rc('font', family='STXihei', size=15)
a=np.array([1,2,3,4,5,6])
plt.bar([1,2,3,4,5,6],group_trip_distance,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('搭乘距离')
plt.ylabel('搭乘次数')
plt.title('乘客搭乘Green TAXI的距离分布')
plt.legend(['搭乘次数'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('0-5公里', '5-10公里', '10-50公里', '50-100公里', '100-200公里', '200公里以上'))
plt.show()

乘客搭乘Green TAXI的距离分布
从乘客搭乘距离分布图上来看,0-5公里短途的数量最多,随着距离的增加搭乘次数明显减少。很明显长途出行搭乘出租车不是一个经济的选择。

乘客叫车方式偏好

Green TAXI的定位是Yellow TAXI的补充,因此对于Green TAXI的运营区域也有严格的限制,再来看下Green TAXI的载客区域。Green TAXI可以从曼哈顿北部(西110街和东96街的北部),布朗克斯,皇后区(不包括机场),布鲁克林和史坦顿岛的街道上接载乘客,并且可以在任何地方落客。但在曼哈顿北部,布朗克斯,皇后区,布鲁克林和史坦顿岛和机场这些区域,Green TAXI只能进行预约载客。也就是说,如果乘客没有预约,Green TAXI就不能去这些区域载客。下面我们来看下Green TAXI的数据中乘客叫车的方式。

119456484

数据表中的Trip_type字段代表了乘客召唤出租车的方式,1= Street-hail,2= Dispatch。我们按Trip_type字段对数据进行汇总。

#按乘客叫车方式对数据表进行计数汇总
Trip_type=green_taxi.groupby(‘Trip_type ‘)[‘Trip_type ‘].agg(len)

然后汇总乘客叫车方式的分布图。以下为代码和结果。

#绘制乘客叫车方式分布图
plt.rc('font', family='STXihei', size=15)
a=np.array([1,2])
plt.bar([1,2],Trip_type,color='#99CC01',alpha=0.8,align='center',edgecolor='white')
plt.xlabel('叫车方式')
plt.ylabel('搭乘次数')
plt.title('乘客搭乘Green TAXI的方式')
plt.legend(['次数'], loc='upper right')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)
plt.xticks(a,('Street-hail','Dispatch'))
plt.show()

乘客搭乘Green TAXI的方式
从图表中看到,Street-hail即乘客在路边召唤出租车的方式是最主要的叫车方式。Dispatch这类通过调度方式叫车的数量非常少。这里有一点需要说明,2016年1月-6月除了Green TAXI和Yellow TAXI外,还有Uber存在。因此乘客在预约时可能更多的选择了Uber,而非传统的出租车。这里没有Uber同期的数据,仅仅是猜测。

24小时使用趋势(1月数据)

我们再来看下乘客在一天24小时中使用Green TAXI的情况。这里我们只使用了2016年1月的单月数据进行分析。

1

重新导入2016年1月的数据,并提取出每次搭乘的小时数据,将数据表按小时数据进行汇总。绘制24小时Green TAXI的使用变化趋势图。

#重新导入2016年1月的数据
green_taxi1=pd.DataFrame(pd.read_csv('green_tripdata_2016-01.csv'))

#对载客时间进行分列,提取载客的小时数据
time_split = pd.DataFrame((x.split(' ') for x in green_taxi1.lpep_pickup_datetime),index=green_taxi1.index,columns=['pickup_date','pickup_time'])

#将分列后的时间字段与原始数据表合并
green_taxi1=pd.merge(green_taxi1,time_split,right_index=True, left_index=True)

#对合并后的数据表中的时间字段更改为时间格式
green_taxi1['pickup_time']=pd.to_datetime(green_taxi1['pickup_time'])

#将时间字段设置为数据表的索引字段
green_taxi1 = green_taxi1.set_index('pickup_time')

#按小时对数据表进行计算汇总
pickup_time=green_taxi1.resample('H',how=len)

#提取按小时汇总后的VendorID字段
group_pickup_time=pickup_time['VendorID']

前面完成了24小时数据搭乘数据的汇总,下面的代码绘制24小时搭乘趋势图。

#绘制24小时载客趋势图
plt.rc('font', family='STXihei', size=9)
plt.plot(group_pickup_time,'g8',group_pickup_time,'g-',color='#99CC01',linewidth=3,markeredgewidth=3,markeredgecolor='#99CC01',alpha=0.8)
plt.xlabel('24小时')
plt.ylabel('搭乘次数')
plt.title('Green TAXI 24小时搭乘次数')
plt.ylim(0,100000)
plt.grid( color='#95a5a6',linestyle='--', linewidth=1 ,axis='y',alpha=0.4)
plt.show()

Green TAXI 24小时搭乘次数1
从24小时搭乘趋势图来看,每日晚间是Green TAXI的使用高峰。晚间的出租车使用量明显高于早间,并且延续时间较长,从晚间19点的用车高峰一直持续到凌晨。

气温与出租车使用情况的关系

本文开始时,我们在分析1-6月Green TAXI使用趋势时曾假设出租车的使用与气温有关,冬季由于气温较低造成出租车的使用量也较低。下面我们使用2016年1月-6月的天气数据与出租车的搭乘数据进行相关分析,来看下这两者间是否有关联。

296634fa-e13d-42d7-8dcf-bd48a3ecb231-2060x1236

首先对出租车搭乘数据进行预处理,包括更改字段格式以及对数据进行按天汇总和提取工资。下面是每个步骤的代码及说明。

#将2016年1-6月数据表中载客时间字段更改为时间格式
green_taxi['lpep_pickup_datetime']=pd.to_datetime(green_taxi['lpep_pickup_datetime'])

#将载客时间字段设置为数据表索引列
green_taxi = green_taxi.set_index('lpep_pickup_datetime')

#数据表按天汇总计数
taxi_day=green_taxi.resample('D',how=len)

#提取按天汇总后的VendorID字段值
group_taxi_day=taxi_day['VendorID']

导入2016年1-6月的天气数据,然后从中提取最低气温数据,也就是TMIN字段中的值。用于和出租车搭乘数据进行相关分析。

#导入天气数据
weather_data=pd.DataFrame(pd.read_csv('822632.csv'))

#提取天气数据表中最低低温列数据
group_weather_day=weather_data['TMIN']

准备好两组数据后,对数据进行标准化预处理。

#导入数据预处理库
from sklearn import preprocessing

#对天气数据进行标准化处理
scaler = preprocessing.StandardScaler().fit(group_weather_day)
X_Standard=scaler.transform(group_weather_day)

#对出租车载客数据进行标准化处理
scaler = preprocessing.StandardScaler().fit(group_taxi_day)
Y_Standard=scaler.transform(group_taxi_day)

将预处理后的数据绘制散点图,下面是具体的代码和图表。

#绘制出租车载客量与最低气温散点图
plt.rc('font', family='STXihei', size=15)
plt.scatter(X_Standard,Y_Standard,80,color='white',marker='+',edgecolors='#052B6C',linewidth=2,alpha=0.8)
plt.xlabel('最低气温')
plt.ylabel('搭乘数量')
plt.title('最低气温与Green TAXI搭乘数量')
plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='both',alpha=0.4)
plt.show()

最低气温与Green TAXI搭乘数量
从散点图中来看,最低气温与出租车的搭乘数量间并没有明显的联系。出租车的搭乘数量一致维持固定的区间内,并没有因为最低气温的变化有显著的变化。下面我们使用回归分析计算两者的相关性。

将每日的最低气温设置为自变量X,每日出租车的载客量设置为因变量Y。然后使用线性回归模型来计算判定系数R方。

#将每日最低气温设置为自变量X
X = np.array(weather_data[['TMIN']])

#将每日出租车载客量设置为因变量Y
Y = np.array(taxi_day[['VendorID']])

#导入线性回归模型
from sklearn import linear_model
clf = linear_model.LinearRegression()
clf.fit (X,Y)

#计算判断系数R方
clf.score(X,Y)
0.0093570505543095761

判断系数为0.0009,说明自变量对因变量的解释度较低,换句话说最低气温的变化与出租车载客量间没有联系。

—【所有文章及图片版权归 蓝鲸(王彦平)所有。欢迎转载,但请注明转自“蓝鲸网站分析博客”。】—

Comments

  1. 斯内克 says:

    蓝鲸,您好,请问你的案例中的源数据哪里可以下载?

  2. 可可可乐 says:

    王老师,您好,请问哪里可以下载源数据?

  3. 风之谷 says:

Dying进行回复 取消回复

*