共享单车数据爬取_共享单车数据可视化分析

8f78ac5d3d2ccaa9153812b85ad13463.png

共享单车逐渐成为大家生活中不可缺少的一部分,为大家带来方便的同时也需要对单车使用情况做出数据分析,以便更好的根据分析结果分配车辆,选择使用时间较少的季节进行维修,乃至对易损坏地区增加维修等等措施。
这次的数据分析目标是找出与消费者租车需求相关的因素,从而更好地调控车辆布置,更好地服务骑友。



话不多说,首先导入我们从Kaggle中下载的数据。

获得数据(导入数据)

import numpy as np
import pandas as pd
import datetime
bikedata = pd.read_csv("C://Users//hp//ShareBikeData//train.csv")
#查看数据总数
bikedata.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10886 entries, 0 to 10885
Data columns (total 12 columns):
datetime      10886 non-null object
season        10886 non-null int64
holiday       10886 non-null int64
workingday    10886 non-null int64
weather       10886 non-null int64
temp          10886 non-null float64
atemp         10886 non-null float64
humidity      10886 non-null int64
windspeed     10886 non-null float64
casual        10886 non-null int64
registered    10886 non-null int64
count         10886 non-null int64
dtypes: float64(3), int64(8), object(1)
memory usage: 1020.6+ KB

可以看到一共有10886条数据,不存在缺失值,也就是说数据清洗较为方便。

查看一下数据表格的样子

bikedata.head()

edcc13195f7ab1df137e107c91518d08.png

观察数据

观察各个行列,首先不方便的是列名是英文名,且值出日期外都为数值型,不是很直观,我们第一步进行列名重命名,其次对season holiday workingday weather值进行处理,或是建立字典或是其他。
对于日期列,可以提取的信息很多,比如对各个时间段进行分割、比较,或许也能得出相关性较强的关系。

通过查阅信息,我们得到如下对应关系:

datatime —— 日期+时间
season (季节)—— 1:春天;2:夏天;3:秋天;4:冬天
holiday (是否为节假日)
workingday (工作日)——1:工作日 ;0:周末
weather(天气)—— 1:晴天,多云;2:雾天,阴;3:小雪,小雨; 4:大雨,大雪,大雾
temp —— 气温摄氏度
atemp —— 体感温度
humidity —— 湿度
windspeed —— 风速
casual —— 非注册用户个数
registered —— 注册用户个数
count —— 给定日期时间(每小时)总租车人数

#查看统计信息
bikedata.describe()

b7ed5e286113df5506652f680d30226f.png

3. 数据清洗

由于数据不存在缺失值,且已经对season、weather等列进行了OneHot编码,故数据清洗只需要进行列名重命名,便可以进行特征工程了。

colNameDict = {
    'season':'季节',
    'holiday':'节假日',
    'workingday':'工作日',
    'weather':'天气',
    'temp':'摄氏温度',
    'atemp':'体感温度',
    'humidity':'湿度', 
    'windspeed':'风速',
    'casual':'非注册用户个数',
    'registered':'注册用户个数',
    'count':'租车总人数'
}
bikeDf = pd.DataFrame(bikedata)
bikeDf.rename(columns = colNameDict,inplace = True)
bikeDf.head()

080790a5c4583f8832ffac6d5c48ecf1.png

之所以没有将datatime列重命名,是因为在后续的操作中会将时间分割。等分割为不同列时,再进行更有效的命名。

4 数据处理

#将日期列分割为年、月、日、星期等信息
#获取日期
def getday(x):
    return x.split()[0]
#使用datatime的apply函数获取日期
bikeDf['日期'] = bikeDf.datetime.apply(getday)

bikeDf['日期'].head()
0    2011-01-01
1    2011-01-01
2    2011-01-01
3    2011-01-01
4    2011-01-01
Name: 日期, dtype: object
#获取时间
def get_hour(x):
    hour = x.split()[1].split(':')[0]
    return hour
#使用datatime的apply函数获取小时数
bikeDf['时刻']= bikeDf.datetime.apply(get_hour)
bikeDf['时刻'].head()
0    00
1    01
2    02
3    03
4    04
Name: 时刻, dtype: object
#定义获取星期数的函数
def get_weekday(x):
    dateStr = x.split()[0]
    dateDT = datetime.datetime.strptime(dateStr,'%Y-%m-%d')
    week_day = dateDT.weekday()
    return week_day
#获取星期数
bikeDf['星期'] =bikeDf.datetime.apply(get_weekday)
bikeDf['星期'].head()
0    5
1    5
2    5
3    5
4    5
Name: 星期, dtype: int64
#定义获取月份的函数,依然使用month()函数获得相应的月份
def get_month(x):
    dateStr = x.split()[0]
    dateDT = datetime.datetime.strptime(dateStr,'%Y-%m-%d')
    month = dateDT.month
    return month
#获取月份数
bikeDf['月份'] = bikeDf.datetime.apply(get_month)
bikeDf['月份'].head()
0    1
1    1
2    1
3    1
4    1
Name: 月份, dtype: int64

对于日期列的处理就暂时进行到这里,我们再次查看一下数据

bikeDf.head(10)

e28efeb66f2311cc2376360312a7bd59.png

数据挖掘

  1. 相关性分析

使用pandas的corr()函数计算各个列的相关性

correlation = bikeDf[['季节','节假日','工作日','天气','摄氏温度','体感温度','湿度','风速',
'时刻','星期',、'月份','非注册用户个数','注册用户个数','租车总人数']].corr()
correlation

c46b81f01f459a477b55dce57e1ad708.png

直观的看各个相关性数据是不是很头疼?
我看的时候就是看着后头忘了前头,不过咱会画图啊,用一种叫做 热图 的图形可以用颜色的深浅表达出相关性的大小!

1.1相关性的可视化

实际操作中seaborn也会出现中文乱码现象,搜索出的解决方案是添加一行代码
------- sns.set_style('whitegrid',{'font.sans-serif':['simhei','Arial']}) 
%matplotlib inline
#导入可视化包
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid',{'font.sans-serif':['simhei','Arial']})
#定义一个图形
fig = plt.figure(figsize = (12,12))
sns.heatmap(correlation,vmax = 1,square = True,annot=True)
<matplotlib.axes._subplots.AxesSubplot at 0x11d225be9b0>

3ca799cad611487207664e6c1ffce3ac.png

当相关性大于0.3时说明二者存在相关关系,由此我们看见以下几点:
1.温度租车人数存在较强的相关,不严谨的说即温度越高租车人数越多;
2.湿度租车人数存在较强的相关,湿度越大租车人数越少(雨雪天气使用人数减弱);
3.注册用户租车总人数之间存在正相关,说明注册用户更偏向于选择使用单车;(应该尽量将非注册用户转化为注册用户)
4.工作日非注册用户个数存在相关,意味着在上班的时间非注册用户更偏向于不使用单车;
5.如温度与体感温度、湿度与天气、季节等虽然具有较强相关性,但是其实是一个特征,这种相关性对本次的分析价值很小。

1.2可视化分析

之前我们计算过数据统计描述信息,但是同样的数据太多,眼花缭乱,因此考虑将统计信息进行可视化,也就是绘制 箱形图

根据相关性的大小我们对以下分类变量作出箱形图: ‘租车总人数’‘时刻’ ‘月份’‘租车总人数’ ‘星期’‘租车总人数’ ‘季节’‘租车总人数’ ‘天气’‘租车总人数’ ‘节假日’‘租车总人数’ ‘周末’‘租车总人数’ ‘租车总人数’随时间变化图像

plt.style.use('ggplot')#ggplot是plt的一种表格风格,
#可以使用print(plt.style.available)显示可供选择的类型
print(plt.style.available)#可以看到有ggplot这种风格
['bmh', 'classic', 'dark_background', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark-palette', 'seaborn-dark', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'seaborn', '_classic_test']
#定义图像的尺寸
fig = plt.figure(figsize = (16,24))
<matplotlib.figure.Figure at 0x11d22b6c7f0>
#设置图像的大标题
fig.suptitle("共享单车数据分析",fontsize=16,fontweight="bold")
print('标题设置成功!')
标题设置成功!
#添加第一个视图
ax1 = fig.add_subplot(4,2,1)
sns.boxplot(data = bikeDf,y = '租车总人数')
plt.title('租车人数箱形图')
plt.ylabel('租车人数')
print('第一个视图完成!')
第一个视图完成!

4d62fa9bfdbbb5cf819a11032c2bdbc5.png

每小时租车人数的中位数在150左右,大部分分布在50-300之间,

#添加第二个视图
ax2 = fig.add_subplot(4,2,2)
sns.boxplot(data = bikeDf,x= '月份',y = '租车总人数',hue = '工作日')
ax2.set(ylabel ='租车总人数', xlabel ='月份',title = '月份与租车人数箱形图')
print('第二个视图完成!')
第二个视图完成!

acb9fdd336ce9858e802934bd9f660a3.png

可以看见,从五月份开始,租车进入旺季,整体租车人数有很大提升,一直到11月份,旺季共6个月。其中非工作日用车数量大于工作日,主要由于天气暖和,非工作日短程游玩人数增多等因素。

#添加第三个视图
ax3 = fig.add_subplot(4,2,3)
sns.boxplot(data = bikeDf,x= '工作日',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='工作日',title = '工作日与租车人数箱形图')
print('第三个视图完成!')
第三个视图完成!

59790d77271bb153279d6969ada9f32c.png

可见非工作日的用车人数大于工作日,但二者相差不大,因为工作日中上下班时刻用车较多。

#添加第四个视图
ax4 = fig.add_subplot(4,2,4)
sns.boxplot(data = bikeDf,x= '时刻',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='时刻',title = '时刻与租车人数箱形图')
print('第四个视图完成!')
第四个视图完成!

e335af093ec80edc20112ae5e5ba3718.png

不出意料的,在上下班高峰期用车人数很多。不过对于22点以后仍然会有不少人用车的现象如果得到更多的比如地域等信息,是很值得继续挖掘的。

#添加第五个视图
ax5 = fig.add_subplot(4,2,5)
sns.boxplot(data = bikeDf,x= '季节',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='季节',title = '季节与租车人数箱形图')
print('第五个视图完成!')
第五个视图完成!

9280b8c7f6d9d9767141c002f29745e8.png

春寒料峭,大家对刚刚过去的寒冬仍然心有余悸,很多时候潜意识不喜欢使用单车,故用车人数很少,冬季由于初期不是很寒冷,还是有较大的用车总数。

#添加第六个视图
ax3 = fig.add_subplot(4,2,6)
sns.boxplot(data = bikeDf,x= '天气',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='天气',title = '天气与租车人数箱形图')
print('第六个视图完成!')
第六个视图完成!

6cd8e28b48affa24e4f8c551397d64cf.png

可见雨雪天气抑制用车作用非常明显。

#添加第七个视图
ax3 = fig.add_subplot(4,2,7)
sns.boxplot(data = bikeDf,x= '节假日',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='节假日',title = '节假日与租车人数箱形图')
print('第七个视图完成!')
第七个视图完成!

3f4882a346deabcf3a9cf724f4e51830.png

节假日外出游玩使用单车骑行较多,所以人数分布多于非节假日。

#添加第八个视图
ax3 = fig.add_subplot(4,2,8)
sns.boxplot(data = bikeDf,x= '星期',y = '租车总人数')
ax3.set(ylabel ='租车总人数', xlabel ='星期',title = '星期几与租车人数箱形图')
print('第八个视图完成!')
第八个视图完成!

a908b189e75d1a14befacce37d2c542c.png

周末的用车数量明显大于工作日,这与之前的分析结果是吻合的。

除以上离散的变量之外,还有温度这种连续变量也需要进行可视化,如下:

#使用pd.cut将连续的体感温度、湿度、风速离散化
bikeDf['体感温度_split']= pd.cut(bikeDf['体感温度'],4)
bikeDf['湿度_split']= pd.cut(bikeDf['湿度'],5)
bikeDf['风速_split']= pd.cut(bikeDf['风速'],4)
# 将季节1234对应到春夏秋冬(使用映射函数.map)
bikeDf["季节"]=bikeDf["季节"].map({1:"春季",2:"夏季",3:"秋季",4:"冬季"})
sns.FacetGrid(data = bikeDf,row = '湿度_split',aspect = 2.2).
map(sns.barplot,'体感温度_split','租车总人数','季节',hue_order=["春季"
,"夏季","秋季","冬季"],palette = 'deep',ci= None).add_legend()

plt.xticks(rotation=60)
(array([0, 1, 2, 3]), <a list of 4 Text xticklabel objects>)

04a959e1f95bf8c935f390e374f50b26.png

由于秋天湿度较低,温度也适宜,在各个图表中,秋季的表现均不俗。

在温度位于10到40度之间,湿度40到80之间的条件下,租车较多。进一步说,干燥的夏天和湿润的冬天以及秋天是租车人数较多的时候。

接下来可视化不同季节各小时段租车人数情况:

plt.style.use('ggplot')
sns.FacetGrid(data = bikeDf,size = 6,aspect =1.5).
map(sns.pointplot,'时刻','租车总人数','季节',hue_order=["春季"
,"夏季","秋季","冬季"],paletter = 'deep',ci= None).add_legend()
<seaborn.axisgrid.FacetGrid at 0x11d20aa95c0>

690cdcceff039efad405e5580ed8caa6.png

可见时刻用车辆的变化与季节的关系不大,即使是冬天相对于其他时刻,上下班(7:00-9:00/17:00-19:00)依然是用车的高峰期;
春季用车人数少,其他季节相差不大;
白天每个时刻租车人数较为稳定,在250左右。

接下来是工作日与租车人数关系的可视化:

sns.FacetGrid(data = bikeDf,size = 6,aspect =1.5).
map(sns.pointplot,'时刻','租车总人数','工作日',hue_order=[1,0],paletter = 'deep',
ci= None).add_legend()
<seaborn.axisgrid.FacetGrid at 0x11d20962e10>

64034f00beab03d07e3cb1542a72fdbf.png

工作日与非工作日的用车需求完全不同,非工作日不存在上下班高峰,用车需求在中午达到最大,可能是大多数人会起床较晚。而用车更多用于短距离的游玩,长距离的旅途使用其他交通工具。

接下来是不同天气下的各月份用车数量的可视化:

#定义字典,将one-hot编码的数据重新还原成原有信息
bikeDf['天气']= bikeDf['天气'].map({1:"晴天",2:"多云",3:"下雨",4:"风暴"})
#选择出所需要的数据做成一张表格
bikeDf[['租车总人数','月份','天气']].pivot_table(values = '租车总人数',index = '月份',
        columns = '天气',aggfunc= 'mean')

2d62a958e1cd3ba899c7908c422d705d.png
# 可视化
sns.FacetGrid(data=bikeDf,size=6,aspect=1.5).
map(sns.pointplot,"月份","租车总人数","天气",hue_order=["晴天","多云","下雨","风暴"],paletter="deep",ci=None).
add_legend()
<seaborn.axisgrid.FacetGrid at 0x11d1f7e70f0>

27f6526258db5ff41302ad9eab0ee5ed.png

晴天与多云是租车的旺天气,5-10月气温较高,租车人数上升。所以5-10月的晴天和多云天气是租车人数最多的时候。

本次分析着重于数据的可视化,因此对于机器学习建模所需要的如剔除异常值等方法并没有运用,不过看过社群中大神继续深入分析,并在kaggle上取得8%排名的行为佩服不已。在学习下一关的过程中我会继续完善这个项目,榜样的力量是巨大的!

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值