数据探索性分析-共享单车数据分析


  本文是就一套经典的共享单车租用情况的数据集做的数据分析与探索。本次对于数据的处理是在和鲸工作台完成

 数据来源及描述

本次数据来自与和鲸社区,采用csv文件。数据共10886行,12列,部分如下:

和鲸社区还有数据概览查看,非常人性了,本数据集的概览如下,在数据概览中我们可以看到数据集的每一个数据的各种基本情况,是否有missing(空值),是什么类型等基本属性:

接下来解释一下本次数据集中的各项数据的含义:

datetime:代表时间,具体到年月日时

season:season数据有1,2,3,4四个属性分别代表春夏秋冬

holiday:0代表非节假日,1代表节假日

workingday:0代表周末,1代表工作日

weather:1代表晴天,2代表雾天,3代表雪天,4代表雨天

temp:温度

atemp:体感温度

humidity:湿度

windspeed:风速

count:总租车数目

casual:非注册用户个数

registered:注册用户个数

 问题提出

数据集有有时间数据、季节数据、温度湿度风速等数据。那么我们可以想到

1、总体使用共享单车的用户的趋势是什么呢?总体在上升还是下降

2、季节对于共享单车的使用有影响吗?夏季炎热冬季寒冷,春秋适宜的天气是否能收到骑行人群的喜爱呢

3、一天24小时,使用单车的人数是否有大的变化呢?时间与共享单侧的使用有什么关系呢?

4、天气对于共享单车的使用影响是什么呢?就常识而言,应该好天气骑行人数较多与不好的天气吧,刮风下雨骑车本身就不方便且安全系数高。所以真的是这样吗,那也要考数据在亲眼验证了。

5、风速、温度等对共享单车是的使用有什么影响呢?什么样的风速、怎么样的温度是最合适人群骑行的呢?

6、注册用户数、非注册用户数、总租车数他们之间隐藏着什么秘密呢?

·······

数据的背后永远藏着很多有用又有趣的秘密,人可能会说谎,但是数据不会。让我们一起探讨数据背后的秘密吧

 数据预处理

  • 导入需要的工具包读取前几行数据,得到结果如下:
 1 #导入工具包
 2 import datetime
 3 import numpy as np
 4 import pandas as pd
 5 import seaborn as sns
 6 import matplotlib.pyplot as plt
 7 from pyecharts.charts import *
 8 import pyecharts.options as opts
 9 from pyecharts.faker import Faker
10 from pyecharts.commons.utils import JsCode
1 #读入数据
2 data = pd.read_csv('/home/kesci/input/first_dataset1318/train.csv')
3 data.head()
4 # data.info()

  •  特征预处理以及数据衍生

将season中的1,2,3,4转换为对应的季节单词以及将weather中的数字也转换成对应的英文单词,方便后续查看数据集的时候清晰明了,holiday,workingday就没有进行这样的处理,因为它们只有0和1 代表是和否比较容易记忆。

#数据预处理,将season和weather中对应的数字转换为相应的英文,方便后续查看数据以及使用数据做分析
data['season'] = data['season'].map({1:'spring',2:'summer',3:'autumn',4:'winner'})
data['weather'] = data['weather'].map({1:'Good',2:'Normal',3:'Bad',4:'ver Bad'})

特征衍生,将datetime中的时间单独衍生出来,分为year,month,day,hour,minute,这样我们在后续就可以对年月日等信息进行分别的探讨了。

#特征衍生
data['datetime'] = pd.to_datetime(data['datetime'])

data['year'] = data.datetime.apply(lambda d:d.year)
data['month'] = data.datetime.apply(lambda d:d.month)
data['day'] = data.datetime.apply(lambda d:d.day)
data['hour'] = data.datetime.apply(lambda d:d.hour)
data['minute'] = data.datetime.apply(lambda d:d.minute)
data.head()

查看进行处理后的数据集:

 从数据概览那部分可以知道,本数据集是几乎完善的一个数据集,没有缺失值,没有什么特殊的字符作乱,所以就没有如一些数据般进行处理缺失值、处理杂乱数据等那样的预处理。

当然也可以通过图表来直观看一下

#可视化查询缺失值
import missingno as msno
msno.matrix(data,figsize=(12,5))

得到图片如下所示:

通过图表也可以直观的看到没有缺失值,所以也就没有在对缺失值做处理

接下来就让我们一起进入数据分析的海洋啊!

 

 各变量相关性数据分析与可视化

  • 从相关性先来看一看,共享单车的租用情况与什么有关系

#从相关性先来看一看,共享单车的租用情况与什么有关系
correlation = data[["temp","atemp","casual","registered","humidity","windspeed","count","season","holiday","workingday","weather","datetime"]].corr()
mask = np.array(correlation)
mask[np.tril_indices_from(mask)] = False
fig,ax= plt.subplots()
fig.set_size_inches(20,10)
sns.heatmap(correlation, mask=mask,vmax=.8, square=True,annot=True)
plt.show()

得到相关性图如下所示:

从图中可以简单得到以下几点结论

count (总数)和 registered(注册租用)、casual(非注册)高度正相关,相关系数分别为0.69 与0.97,因为 count = casual + registered ,所以这个正相关和预期相符。

count (总数)和 temp (气温)和atemp(体表温度)正相关,且相关系数都为为 0.39,因为一般来说,气温过低或过高人们都不太愿意出门骑车。

count (总数)和 humidity(湿度)负相关,说明湿度过大的天气骑行的人数不多

windspeed(风速)似乎对租车人数影响不大(0.1),但我们也应该考虑到极端大风天气出现频率应该不高。风速在正常范围内波动应该对人们租车影响不大。

  • 从租车本身以及其与小时、季节、工作日、天气五个方面的箱式图来看一下大家的关系

# 设置绘图格式和画布大小
fig, axes = plt.subplots(nrows=3,ncols=2)#三行两列
fig.set_size_inches(22, 20)

# 添加第一个子图, 租车人数分布的箱线图
sns.boxplot(data=data,y="count",orient="v",ax=axes[0][0])

#添加第二个子图,租车人数季节分布的箱线图
sns.boxplot(data=data,y="count",x="season",orient="v",ax=axes[0][1])

#添加第三个子图,租车人数时间分布的箱线图
sns.boxplot(data=data,y="count",x="hour",orient="v",ax=axes[1][0])

#添加第四个子图,租车人数工作日分布的箱线图
sns.boxplot(data=data,y="count",x="workingday",orient="v",ax=axes[1][1])

#添加第四个子图,租车人数天气分布的箱线图
sns.boxplot(data=data,y="count",x="weather",orient="v",ax=axes[2][0])

# 设置第一个子图坐标轴和标题
axes[0][0].set(ylabel='Count',title="Box Plot On Count")

# 设置第二个子图坐标轴和标题
axes[0][1].set(xlabel='Season', ylabel='Count',title="Box Plot On Count Across Season")

# 设置第三个子图坐标轴和标题
axes[1][0].set(xlabel='Hour Of The Day', ylabel='Count',title="Box Plot On Count Across Hour Of The Day")

# 设置第四个子图坐标轴和标题
axes[1][1].set(xlabel='Working Day', ylabel='Count',title="Box Plot On Count Across Working Day")

# 设置第五个子图坐标轴和标题
axes[2][0].set(xlabel='Weather', ylabel='Count',title="Box Plot On Count Across Weather")

plt.show()

得到如下五个箱式图:

 

从“Hour Of The Day”这幅图看到,此图有双高峰,一个是7- 8点,另外两个是17 -18点。按照日常通勤时间来看,正好是上下班的早晚高峰。
同时从“
Box Plot On Count Across Weather”可以看到ver Bad天气是几乎没怎么人出行的
从天气和工作日也能看出他们之间的细微差别,接下来也会用其他图表的展示来在一次查看他们之间的关系
  •  从时间维度分析:看看共享单车的骑行与年份和月份是什么关系

因为所给数据是2011与2012年的数据,所以绘制了两幅图,一幅是2011年中月份与count(总租车数目)、registered(注册用户数)、casual(非注册用户数)之间的关系,另一幅就是2012年中月份与count(总租车数目)、registered(注册用户数)、casual(非注册用户数)之间的关系

#因为是有两年的数据,为了区分来看,将两年的数据分开来进行
Month_tendency_2011 = data[data['year'] == 2011].groupby('month')[['casual','registered','count']].sum()
Month_tendency_2012 = data[data['year'] == 2012].groupby('month')[['casual','registered','count']].sum()

#绘制2011图像
fig,[ax1,ax2] = plt.subplots(2,1,figsize=(12,15))
plt.subplots_adjust(hspace=0.3)
Month_tendency_2011.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=ax1)
ax1.set_title('2011',fontsize=15)
ax1.grid(linestyle='--',alpha=0.8)
ax1.set_ylim(0,150000)
ax1.set_xlabel('Month',fontsize=13)
ax1.set_ylabel('Count',fontsize=13)

#绘制2012图像
Month_tendency_2012.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=ax2)
ax2.set_title('2012 ',fontsize=15)
ax2.grid(linestyle='--',alpha=0.8)
ax2.set_ylim(0,150000)
ax2.set_xlabel('Month',fontsize=13)
ax2.set_ylabel('Count',fontsize=13)
sns.despine(left=True)

  得到的两幅图如下所示: 

对比两幅图

从年份来看:可以看到2012年相较于2011年总体的count(租车总数目)和registered(注册用户)是大幅增长的,casual(非注册)用户也在增长,虽然增长缓慢,但是也是在增长的趋势发展的。说明经过一年,越来越多的人选择使用共享单车,并且越来越多的人选择注册账户使用共享单车。总体来说行情是向着好的方向发展

从月份来看:两年都是6~9月骑行人数较多,1~2以及12月都人数较少,可以说明6月~9月是骑行旺季,12月~2月是骑行淡季。这样可以在旺季是多投放一批共享单车进入市场使用,而淡季就可以回收一批,以防车辆损坏

  •  从时间维度分析:看看骑行与小时之间有什么关系

#提取出每个小时的骑行需求均值
Hour_tendency = data.groupby('hour')[['casual','registered','count']].mean()

Hour_tendency.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',figsize=(12,6))
plt.grid(linestyle='--',alpha=0.8)
plt.ylim(0,500)
plt.xlim(1,24)
plt.xlabel('Hour',fontsize=13)
plt.ylabel('Count',fontsize=13)
sns.despine(left=True)

  得到的图如下:

 

通过看图可以发现:早上7~8点,晚上5~6点是两个峰值,中午12点左右也有一个小小的峰值,符合正常通勤情况。说明还是很多人会选择用共享单车进行通勤,给大家的生活带来了许多便利

  • 从工作日和非工作日的时间维度来看一下工作日和非工作日对骑行有什么影响

其实不难猜测,工作日的出行时间肯定更符合日常通勤的时间,而非工作日就不一定了,那么就来验证一下:

#工作人和非工作日每小时的骑行是否有差异
plt.figure(figsize=(12,6))
sns.pointplot(x='hour',y='count',hue='workingday',data=data,ci=None,palette='Spectral')
sns.despine(left=True)
plt.xlabel('Hour',fontsize=13)
plt.ylabel('Count',fontsize=13)
plt.grid(linestyle='--',alpha=0.5)
plt.title('workingday',fontsize=15)

得到了这样的结果图:

从图可以看到工作日与非工作日的骑行需求规律反差巨大,非工作日的共享单车苏醒慢,骑行需求高峰出现在12AM~3PM的这段时间内,另外凌晨0AM~4AM的骑行需求大于工作日,周末使劲造,而工作日就如同上一个得到结果一样更符合通勤时间。

  • 看看季节与共享单车的使用情况

做出四个季节与count(总数)的散点图,直观的来看看哪个季节更受骑行喜爱呢

#季节使用情况的散点图
season_Demand=data.groupby(['season','day'])[['count']].sum()
season_Demand.reset_index(inplace=True)
plt.figure(figsize=(12,6))
#jitter : float类型,True/1作用:当数据重合较多时,用该参数做一些调整,也可以设置间距如 (通俗讲,就是让数据分散开)
#palette:调色板名称,作用:用于对数据不同分类进行颜色区别
sns.stripplot(x='season',y='count',data=season_Demand,palette='Set1',jitter=True,alpha=1.0)
sns.despine(left=True)
plt.xlabel('Season',fontsize=13)
plt.ylabel('Count',fontsize=13)
plt.title('Season',fontsize=15)

得到如下结果图:

 通过得到的结果图可以看到骑行人数最多的是秋期,其次是夏季、冬季,最后是春季,结果还挺让人意外,与我们最初预测的春秋宜人天气骑行多于夏冬极致天气的结果是完全不同的。仔细想想,春季是1-3月,而1-3月多数都是春节的时候,那个时候无数的人们都赶回家与家人团聚,所以对于共享单车来说使用的数量也许确实要少很多。当然这也只是我么的一个猜测,具体的还有待于其他数据的辅助得到最终的结果,而对于此数据集我们是不能探究出这个问题了。但是还是觉得春节这个时间段的解释是非常合理的。哈哈哈哈哈。

这也说明数据真是神秘又奇妙的,如果不是通过此次的数据探究,谁能想到是这样的结果呢。

  • 接下里从天气维度来看看,四种不同的天气共享单车的租用情况如何呢? 

其实也不难猜测,肯定是好天气出行的人数更多,雨天、雾天等骑行自行车出行是很不方便的,带来的安全隐患也更大一些,接下来我们用数据来证实我们的猜测

Weather_Demand=data.groupby(['weather','day'])[['count']].sum()
Weather_Demand.reset_index(inplace=True)

# 不同天气的骑行需求散点图 
plt.figure(figsize=(12,6))
sns.stripplot(x='weather',y='count',data=Weather_Demand,palette='Set2',jitter=True,alpha=1.0)
sns.despine(left=True)
plt.xlabel('Season',fontsize=13)
plt.ylabel('Count',fontsize=13)
plt.title('Demand Distribution by Weather',fontsize=15)

得到的散点图如下所示:

#不同天气的骑行需求
plt.figure(figsize=(12,6))
sns.pointplot(x='hour',y='count',hue='weather',data=data,ci=None,palette='Spectral')
sns.despine(left=True)
plt.xlabel('Hour',fontsize=13)
plt.ylabel('Count',fontsize=13)
plt.grid(linestyle='--',alpha=0.5)
plt.title('Demand Tendency by season',fontsize=15)

   散点图和折线图可以很明显的看出来了,好天气骑行需求是最大的,并且极端坏天气的折线图都形不成折现,散点图也是非常少,当然因为极端坏天气也是比较少的,这也与我们上面的预测分析结果是一样的。好天气的骑行人数肯定是最多的

  •  来看一看注册用户和非注册用户他们与各个因素的关系是怎样的呢 

# 衍生特征
data['dif']=data['registered']-data['casual'] # 衍生特征注册用户与非注册用户
fig,axes=plt.subplots(2,2,figsize=(20,8))
plt.subplots_adjust(hspace=0.3,wspace=0.1)

# 图1:月度差异
Month_Dif =data.groupby('month')[['casual','registered']].mean()
Month_Dif.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[0,0])
axes[0,0].set_title('Month ',fontsize=15)
axes[0,0].grid(linestyle='--',alpha=0.8)
axes[0,0].set_xlabel('Month',fontsize=13)
axes[0,0].set_ylabel('Count',fontsize=13)
#图2:小时差异
Hour_Dif = data.groupby('hour')[['casual','registered']].mean()
Hour_Dif.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[0,1])
axes[0,1].set_title('Hour ',fontsize=15)
axes[0,1].grid(linestyle='--',alpha=0.8)
axes[0,1].set_xlabel('Hour',fontsize=13)
axes[0,1].set_ylabel('Count',fontsize=13)
# 图3:工作日差异
H2_1 = data[data.workingday==1].groupby('hour')[['casual','registered']].mean() # 工作日
H2_0 = data[data.workingday==0].groupby('hour')[['casual','registered']].mean() # 非工作日
H2_1.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[1,0])
axes[1,0].set_title('Workingday Hour ',fontsize=15)
axes[1,0].grid(linestyle='--',alpha=0.8)
axes[1,0].set_xlabel('Hour',fontsize=13)
axes[1,0].set_ylabel('Count',fontsize=13)
# 图4:非工作日差异
H2_0.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[1,1])
axes[1,1].set_title('Holiday Hour ',fontsize=15)
axes[1,1].grid(linestyle='--',alpha=0.8)
axes[1,1].set_xlabel('Hour',fontsize=13)
axes[1,1].set_ylabel('Count',fontsize=13)
sns.despine(left=True)

得到结果图

第一幅为两者的月度差异图,可见整体趋势相同,注册用户远高于非注册用户;

第二幅为两者的小时差异图,可见注册用户的小时规律明显,非注册用户则只在12AM~5PM存在峰值,整体差异较大;

第三幅为两者的工作日差异图,可见注册用户工作日小时规律明显,二非注册用户趋势平缓;

第四幅为两者的非工作日差异图,可见非工作日两者差异相较于其他因素差异较小,且趋势相同,值得注意的是注册用户在凌晨更加活跃。

总的来说,注册用户需求远高于非注册用户,注册用户的使用规律明显,而非注册用户受其他因素的影响相对较弱。

  • 接下来看看气温与体表温度之前的关系

采用sns.kdeplot()核密度估计来查看,核密度估计是概率论上用来估计未知的密度函数,属于非参数检验,通过核密度估计图可以比较直观的看出样本数据本身的分布特征,采用二元kde图像来查看

# 温度与体表温度的关系度量
plt.figure(figsize=(10,8))
sns.kdeplot(data['temp'],data['atemp'],shade=True,shade_lowest=False,cut=10,cmap='YlGnBu',cbar=True)
sns.despine(left=True)
plt.grid(linestyle='--',alpha=0.4)
plt.xlim(0,50)
plt.ylim(0,50)
plt.xlabel('Temperature',fontsize=13)
plt.ylabel('Atemp',fontsize=13)
plt.title('correlation of temp and atemp',fontsize=15)

得到的结果如下所示:

 从两者的关系度量图中我们能看出呈现正相关分布,另外根据核密度估计图可知,颜色最深的分布最为集中,所以从图可以看出气温27℃~28℃、体表温度31℃左右的骑行需求是最密集的。

  • 接下来看看气温与湿度的关系

# 温度与湿度的关系度量
plt.figure(figsize=(10,8))
sns.kdeplot(data['temp'],data['humidity'],shade=True,shade_lowest=False,cut=10,cmap='YlGnBu',cbar=True)
sns.despine(left=True)
plt.grid(linestyle='--',alpha=0.4)
plt.xlim(0,40)
plt.ylim(0,110)
plt.xlabel('Temperature',fontsize=13)
plt.ylabel('Humidity',fontsize=13)
plt.title('correlation of temp and humidity',fontsize=15)

得到的结果图如下:

 由图可以看出气温27℃~28℃,湿度80~90骑行需求是最密集的。

  • 最后来看看天气因素与骑行需求之间的关系

将气温和风速作为天气因素分析骑行需求(忽略体表温度,气温即代表了体表温度),使用散点图绘制,散点的大小和颜色代表了骑行量,每个散点代表一天。

 

plt.figure(figsize=(12,6))
plt.scatter(x='temp',y='windspeed',
            s=data['count']/2,
            c='count',cmap='RdBu_r',
            edgecolors='black',linestyle='--',linewidth=0.2,alpha=0.6,
            data=data)
plt.title('Count distribution by temp and windspeed',fontsize=15)
plt.xlabel('Temperature',fontsize=13)
plt.ylabel('Windspeed',fontsize=13)
sns.despine(left=True)

 

得到的散点图如下所示:

不难看出骑行需求较多的分布范围是气温20℃~35℃,风速40以下。所以可见人们更热衷于温暖天气骑行,炎热天气需求也大的原因可能是因为相对于公共交通,骑行更加灵活方便吧。

总结

根据上面得到的图表作出如下简短总结

1、共享单车由注册用户与非注册用户构成,而主要群体以注册用户为主。

2、6月~9月是骑行旺季,12月~2月是骑行淡季

3、四季中骑行人数最多的是夏季,而最少的是春季。这个结果与最初的预计是不太一样的。通过粗略分析,春季为1-3月,多为春节放假时间段,那时候家家户户都在家团圆所以相对来说可能骑行人数就最少了。

3、工作日与非工作日的骑行需求规律反差巨大,非工作日的共享单车苏醒慢,骑行需求高峰出现在12AM~3PM的这段时间内,而工作日的骑行需求高峰是在日常通勤时间段

4、在好天气下选择共享单车的出行的人数最多

5、用户总数在温度达到20-25摄氏度之间达到高峰期,可能因为温度较舒服,人们喜欢骑单车出行

6、气温27℃~28℃,湿度80~90骑行需求是最密集的

7、从注册用户和非注册用户来说,注册用户需求远高于非注册用户,并且注册用户的使用规律明显,而非注册用户受其他因素的影响相对较弱。

当然还有很多其他方面值得进行分析与探讨,得到隐藏在数据背后的秘密。

 

参考文章:https://www.heywhale.com/mw/project/600f920be455800015bd29b1/content(【怀念单车给你我,唯一有过的拥抱】共享单车数据分析)

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM