共享单车项目分析
共享单车项目分析
作者:马建龙
目录
- 提出问题
- 理解数据
- 采集数据
- 导入数据
- 查看数据集信息
- 数据清洗
- 数据预处理
- 数据分析
- 数据可视化
- 方案实施
- 报告撰写
1、提出问题
根据kaggle项目:共享单车的数据进行描述性统计分析,查看不同因素对共享单车使用数量的影响。
2、理解数据
2.1 采集数据
从kaggle网站下载,https://www.kaggle.com/c/bike-sharing-demand
2.1 导入数据
1import numpy as np
2import pandas as pd
3import datetime
1%matplotlib inline
1bike=pd.read_csv("C:/Users/my/data/train(bike).csv")
2.3 查看数据信息
datetime(日期) - hourly date + timestamp
season(季节) - 1 = spring, 2 = summer, 3 = fall, 4 = winter
holiday(是否假日) - whether the day is considered a holiday
workingday(是否工作日) - whether the day is neither a weekend nor holiday
weather(天气等级) -
1: Clear, Few clouds, Partly cloudy 清澈,少云,多云。
2: Mist + Cloudy, Mist + Broken clouds, Mist + Few clouds, Mist 雾+阴天,雾+碎云、雾+少云、雾
3: Light Snow, Light Rain + Thunderstorm + Scattered clouds, Light Rain + Scattered clouds 小雪、小雨+雷暴+散云,小雨+云
4: Heavy Rain + Ice Pallets + Thunderstorm + Mist, Snow + Fog 暴雨+冰雹+雷暴+雾,雪+雾
temp(温度) - temperature in Celsius
atemp(体感温度) - "feels like" temperature in Celsius
humidity(相对湿度) - relative humidity
windspeed(风速) - wind speed
casual(临时租赁数量) - number of non-registered user rentals initiated
registered(会员租赁数量) - number of registered user rentals initiated
count(总租赁数量) - number of total rentals
1bike.shape
(10886, 12)
1bike.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
1bike.head()
| datetime | season | holiday | workingday | weather | temp | atemp | humidity | windspeed | casual | registered | count | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 00:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 01:00:00 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 02:00:00 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 03:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 04:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 |
数据清洗
3.1 选择子集
本数据暂时不用选择子集
3.2 列重命名
1bike.columns=["日期","季节","节假日","工作日","天气","温度","感觉温度","湿度","风速","非注册用户","注册用户","数量"]
1bike.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 00:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 |
| 1 | 2011-01-01 01:00:00 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 |
| 2 | 2011-01-01 02:00:00 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 |
| 3 | 2011-01-01 03:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 |
| 4 | 2011-01-01 04:00:00 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 |
3.3 缺失值处理
- 本数据没有缺失值
3.4 替换值
- 本数据变量中的分类变量有:季节,节假日,工作日,天气,需要进行变换
1jijie={1:"春",2:"夏",3:"秋",4:"冬"}
1jijie
{1: '春', 2: '夏', 3: '秋', 4: '冬'}
1bike["季节"]=bike["季节"].map(jijie)
1tianqi={1:"晴,少云",2:"薄雾,少云",3:"小雨,小雪,散云",4:"大雨,冰雹,雪,雾"}
1bike["天气"]=bike["天气"].map(tianqi)
- 节假日和工作日,需要先把日期列转换为date格式
3.5 重复值处理
1bike.drop_duplicates(inplace=True)
1bike.shape#没有重复值
(10886, 12)
3.6 字符类型转换
1bike.dtypes
日期 object
季节 object
节假日 int64
工作日 int64
天气 object
温度 float64
感觉温度 float64
湿度 int64
风速 float64
非注册用户 int64
注册用户 int64
数量 int64
dtype: object
1bike.loc[0,"日期"].split(" ")
['2011-01-01', '00:00:00']
1a=[]
2b=[]
3for i in bike["日期"]:
4 c=i.split(" ")
5 a.append(c[0])
6 b.append(c[1])
7
1bike["日期"]=a
1bike["时间"]=b
1bike.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时间 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 00:00:00 |
| 1 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 01:00:00 |
| 2 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 02:00:00 |
| 3 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 03:00:00 |
| 4 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 04:00:00 |
1bike["日期"]=pd.to_datetime(bike["日期"], format='%Y-%m-%d', errors='coerce')
1bike.dtypes
日期 datetime64[ns]
季节 object
节假日 int64
工作日 int64
天气 object
温度 float64
感觉温度 float64
湿度 int64
风速 float64
非注册用户 int64
注册用户 int64
数量 int64
时间 object
dtype: object
1bike.loc[0,"日期"].weekday()
5
1xingqi={0:"星期一",1:"星期二",2:"星期三",3:"星期四",4:"星期五",5:"星期六",6:"星期日"}
1a=[]
2for i in bike["日期"]:
3 b=i.weekday()
4 a.append(b)
1bike["星期"]=a
1bike["星期"]=bike["星期"].map(xingqi)
1bike.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时间 | 星期 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 00:00:00 | 星期六 |
| 1 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 01:00:00 | 星期六 |
| 2 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 02:00:00 | 星期六 |
| 3 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 03:00:00 | 星期六 |
| 4 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 04:00:00 | 星期六 |
1bike.loc[0,"日期"].month
1
1a=[]
2for i in bike["日期"]:
3 b=i.month
4 a.append(b)
1bike["月份"]=a
1b=[]
2for i in bike["时间"]:
3 a=i.split(":")
4 b.append(a[0])
1bike["时间"]=b
1bike.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时间 | 星期 | 月份 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 00 | 星期六 | 1 |
| 1 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 01 | 星期六 | 1 |
| 2 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 02 | 星期六 | 1 |
| 3 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 03 | 星期六 | 1 |
| 4 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 04 | 星期六 | 1 |
1bike2=pd.read_csv("C:/Users/my/data/train(bike).csv")
1bike2.columns=["日期","季节","节假日","工作日","天气","温度","感觉温度","湿度","风速","非注册用户","注册用户","数量"]
1a=[]
2b=[]
3for i in bike2["日期"]:
4 c=i.split(" ")
5 a.append(c[0])
6 b.append(c[1])
1bike2["日期"]=a
2bike2["时段"]=b
1bike2.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时段 | 星期 | 月份 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 00 | 5 | 1 |
| 1 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 01 | 5 | 1 |
| 2 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 02 | 5 | 1 |
| 3 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 03 | 5 | 1 |
| 4 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 04 | 5 | 1 |
1bike2["日期"]=pd.to_datetime(bike2["日期"], format='%Y-%m-%d', errors='coerce')
1a=[]
2for i in bike2["日期"]:
3 b=i.weekday()
4 a.append(b)
1bike2["星期"]=a
1a=[]
2for i in bike["日期"]:
3 b=i.month
4 a.append(b)
1bike2["月份"]=a
1b=[]
2for i in bike2["时段"]:
3 a=i.split(":")
4 b.append(a[0])
1bike2["时段"]=b
1bike2.dtypes
日期 datetime64[ns]
季节 int64
节假日 int64
工作日 int64
天气 int64
温度 float64
感觉温度 float64
湿度 int64
风速 float64
非注册用户 int64
注册用户 int64
数量 int64
时段 int64
星期 int64
月份 int64
dtype: object
1bike2["时段"]=bike2["时段"].astype("int64")
1bike2.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时段 | 星期 | 月份 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 0 | 5 | 1 |
| 1 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 1 | 5 | 1 |
| 2 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 2 | 5 | 1 |
| 3 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 3 | 5 | 1 |
| 4 | 2011-01-01 | 1 | 0 | 0 | 1 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 4 | 5 | 1 |
1bike.head()
| 日期 | 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时间 | 星期 | 月份 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 81 | 0.0 | 3 | 13 | 16 | 00 | 星期六 | 1 |
| 1 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 8 | 32 | 40 | 01 | 星期六 | 1 |
| 2 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.02 | 13.635 | 80 | 0.0 | 5 | 27 | 32 | 02 | 星期六 | 1 |
| 3 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 3 | 10 | 13 | 03 | 星期六 | 1 |
| 4 | 2011-01-01 | 春 | 0 | 0 | 晴,少云 | 9.84 | 14.395 | 75 | 0.0 | 0 | 1 | 1 | 04 | 星期六 | 1 |
- 在这一步有些差错,所以就做了2个Df:bike和bike2。bike是把数值型的转换为字符型,是用来画表用的,让表格更加直观,bike2是把所有变量转化为数值型,是为以后构建模型方便。
4 进行数据分析与可视化
1g = sns.PairGrid(bike2)
2g.map(plt.scatter)#这个图没啥用
<seaborn.axisgrid.PairGrid at 0x1d792208>
1corrDf = bike2.corr()
2corrDf
| 季节 | 节假日 | 工作日 | 天气 | 温度 | 感觉温度 | 湿度 | 风速 | 非注册用户 | 注册用户 | 数量 | 时段 | 星期 | 月份 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 季节 | 1.000000 | 0.029368 | -0.008126 | 0.008879 | 0.258689 | 0.264744 | 0.190610 | -0.147121 | 0.096758 | 0.164011 | 0.163439 | -0.006546 | -0.010553 | 0.971524 |
| 节假日 | 0.029368 | 1.000000 | -0.250491 | -0.007074 | 0.000295 | -0.005215 | 0.001929 | 0.008409 | 0.043799 | -0.020956 | -0.005393 | -0.000354 | -0.191832 | 0.001731 |
| 工作日 | -0.008126 | -0.250491 | 1.000000 | 0.033772 | 0.029966 | 0.024660 | -0.010880 | 0.013373 | -0.319111 | 0.119460 | 0.011594 | 0.002780 | -0.704267 | -0.003394 |
| 天气 | 0.008879 | -0.007074 | 0.033772 | 1.000000 | -0.055035 | -0.055376 | 0.406244 | 0.007261 | -0.135918 | -0.109340 | -0.128655 | -0.022740 | -0.047692 | 0.012144 |
| 温度 | 0.258689 | 0.000295 | 0.029966 | -0.055035 | 1.000000 | 0.984948 | -0.064949 | -0.017852 | 0.467097 | 0.318571 | 0.394454 | 0.145430 | -0.038466 | 0.257589 |
| 感觉温度 | 0.264744 | -0.005215 | 0.024660 | -0.055376 | 0.984948 | 1.000000 | -0.043536 | -0.057473 | 0.462067 | 0.314635 | 0.389784 | 0.140343 | -0.040235 | 0.264173 |
| 湿度 | 0.190610 | 0.001929 | -0.010880 | 0.406244 | -0.064949 | -0.043536 | 1.000000 | -0.318607 | -0.348187 | -0.265458 | -0.317371 | -0.278011 | -0.026507 | 0.204537 |
| 风速 | -0.147121 | 0.008409 | 0.013373 | 0.007261 | -0.017852 | -0.057473 | -0.318607 | 1.000000 | 0.092276 | 0.091052 | 0.101369 | 0.146631 | -0.024804 | -0.150192 |
| 非注册用户 | 0.096758 | 0.043799 | -0.319111 | -0.135918 | 0.467097 | 0.462067 | -0.348187 | 0.092276 | 1.000000 | 0.497250 | 0.690414 | 0.302045 | 0.246959 | 0.092722 |
| 注册用户 | 0.164011 | -0.020956 | 0.119460 | -0.109340 | 0.318571 | 0.314635 | -0.265458 | 0.091052 | 0.497250 | 1.000000 | 0.970948 | 0.380540 | -0.084427 | 0.169451 |
| 数量 | 0.163439 | -0.005393 | 0.011594 | -0.128655 | 0.394454 | 0.389784 | -0.317371 | 0.101369 | 0.690414 | 0.970948 | 1.000000 | 0.400601 | -0.002283 | 0.166862 |
| 时段 | -0.006546 | -0.000354 | 0.002780 | -0.022740 | 0.145430 | 0.140343 | -0.278011 | 0.146631 | 0.302045 | 0.380540 | 0.400601 | 1.000000 | -0.002925 | -0.006818 |
| 星期 | -0.010553 | -0.191832 | -0.704267 | -0.047692 | -0.038466 | -0.040235 | -0.026507 | -0.024804 | 0.246959 | -0.084427 | -0.002283 | -0.002925 | 1.000000 | -0.002266 |
| 月份 | 0.971524 | 0.001731 | -0.003394 | 0.012144 | 0.257589 | 0.264173 | 0.204537 | -0.150192 | 0.092722 | 0.169451 | 0.166862 | -0.006818 | -0.002266 | 1.000000 |
1corrDf["数量"].sort_values(ascending=False)
数量 1.000000
注册用户 0.970948
非注册用户 0.690414
时段 0.400601
温度 0.394454
感觉温度 0.389784
月份 0.166862
季节 0.163439
风速 0.101369
工作日 0.011594
星期 -0.002283
节假日 -0.005393
天气 -0.128655
湿度 -0.317371
Name: 数量, dtype: float64
1fig=plt.figure(figsize=(12,12))
2ax1=fig.add_subplot(1,1,1)
3sns.set(style='dark')
4sns.heatmap(corrDf,ax=ax1,vmax=1,square=False,annot=True,cmap='YlGnBu',linewidths=.5)
5plt.title('Heatmap on Correlation',fontsize=30,color='white')
6plt.xticks(fontsize=10,color='white',rotation=45)
7plt.yticks(fontsize=10,color='white')
8plt.show()
- 这一步进行了相关性分析,从结果上可以看出,影响因素的排名为:时段>温度>感觉温度>湿度>月份>季节>天气>风速,其中正相关的有:时段,温度,感觉温度,月份,季节,风速;负相关的有湿度,天气
4.1查看月份与共享单车的影响
1import seaborn as sns
2import matplotlib.pyplot as plt
1fig,(ax1,ax2)=plt.subplots(nrows=2)
2fig.set_size_inches(9,10)
3sns.barplot(data=monthg,x="月份",y="数量",ax=ax1)
4sns.pointplot(data=monthg,x="月份",y="数量",ax=ax1)
5ax1.set(xlabel="月",ylabel="数量",title="每月的共享单车数量")
6
7sns.barplot(data=monthweek,x="月份",y="数量",hue="星期",ax=ax2)
8ax2.set(xlabel="月",ylabel="数量",title="每月的共享单车数量")
[Text(0,0.5,'数量'), Text(0.5,0,'月'), Text(0.5,1,'每月的共享单车数量')]
1rizhu=pd.DataFrame(bike.groupby("月份")["注册用户"].mean()).reset_index()
2rifeizhu=pd.DataFrame(bike.groupby("月份")["非注册用户"].mean()).reset_index()
3ri=pd.DataFrame(bike.groupby("月份")["数量"].mean()).reset_index()
1fig,ax1=plt.subplots()
2fig.set_size_inches(20, 20)
3sns.pointplot(data=rifeizhu,x="月份",y="非注册用户",color="green",ax=ax1,label="非注册用户")
4sns.pointplot(data=rizhu,x="月份",y="注册用户",color="red",ax=ax1,label="非注册用户")
5sns.pointplot(data=ri,x="月份",y="数量",color="black",ax=ax1,label="总数量")
6ax1.set(xlabel="月份",ylabel="数量",title="不同月份下不同用户类型的增长情况")
[Text(0,0.5,'数量'), Text(0.5,0,'月份'), Text(0.5,1,'不同月份下不同用户类型的增长情况')]
- 从上图可以看出,5-10月的共享单车使用量比较高,而且变化比较稳定,11-12月是一个递减趋势,1-4月是一个递增趋势,虽然11、12月是递减趋势,但是仍然比1、2、3、4这四个月份的使用量高。初步分析的天气因素的温度造成的,温度越低,人们使用共享单车的数量越少。
4.2 查看季节与共享单车数量的关系
1monthg=pd.DataFrame(bike.groupby("月份")["数量"].mean()).reset_index()
2monthg=monthg.sort_values(by="数量",ascending=False)
3monthweek=pd.DataFrame(bike.groupby(["月份","星期"],sort=True)["数量"].mean()).reset_index()
4monthweek=monthweek.sort_values(by="数量",ascending=False)
1monthg.head()
| 月份 | 数量 | |
|---|---|---|
| 5 | 6 | 242.031798 |
| 6 | 7 | 235.325658 |
| 7 | 8 | 234.118421 |
| 8 | 9 | 233.805281 |
| 9 | 10 | 227.699232 |
1jijiedf=pd.DataFrame(bike.groupby("季节")["数量"].mean()).reset_index()
1jijieshijian=pd.DataFrame(bike.groupby(["季节","时间"],sort=True)["数量"].mean()).reset_index()
2jijiexingqi=pd.DataFrame(bike.groupby(["季节","星期"],sort=True)["数量"].mean()).reset_index()
1fig,(ax1,ax2,ax3)=plt.subplots(nrows=3)
2fig.set_size_inches(9,10)
3sns.barplot(data=jijiedf,x="季节",y="数量",ax=ax1)
4sns.pointplot(data=jijiedf,x="季节",y="数量",ax=ax1)
5ax1.set(xlabel="季节",ylabel="数量",title="每个季节共享单车数量")
6
7sns.barplot(data=jijieshijian,x="季节",y="数量",hue="时间",ax=ax2)
8ax2.set(xlabel="季节",ylabel="数量",title="每月的共享单车数量")
9
10sns.barplot(data=jijiexingqi,x="季节",y="数量",hue="星期",ax=ax3)
11ax3.set(xlabel="季节",ylabel="数量",title="每月的共享单车数量")
[Text(0,0.5,'数量'), Text(0.5,0,'季节'), Text(0.5,1,'每月的共享单车数量')]
- 从上图看出秋季的使用量最高,对应的是7,8,9月份,春季的使用量最低,对应的是1,2,3月份,与月份图想吻合。而且在季节星期和月份星期的图中都可以看出,不论哪个月份,哪个季节,每周中7天的共享单车使用数量都没有明显的差别。
4.3 查看每个时间断与共享单车数量的关系
1shijianweek=pd.DataFrame(bike.groupby(["时间","星期"],sort=True)["数量"].mean()).reset_index()
2shijiajijie=pd.DataFrame(bike.groupby(["时间","季节"],sort=True)["数量"].mean()).reset_index()
3shijianyuefen=pd.DataFrame(bike.groupby(["时间","月份"],sort=True)["数量"].mean()).reset_index()
4shijian=pd.DataFrame(bike.groupby("时间")["数量"].mean()).reset_index()
5
6fig,(ax1,ax2,ax3,ax4)=plt.subplots(nrows=4)
7fig.set_size_inches(9,10)
8sns.pointplot(data=shijian,x="时间",y="数量",ax=ax1)
9ax1.set(xlabel="时间",ylabel="数量",title="不同时间断的共享单车数量")
10
11sns.pointplot(data=shijianweek,x="时间",y="数量",hue="星期",ax=ax2)
12ax2.set(xlabel="时间",ylabel="数量",title="每周不同时间段的共享单车数量")
13
14sns.pointplot(data=shijiajijie,x="时间",y="数量",hue="季节",ax=ax3)
15ax3.set(xlabel="时间",ylabel="数量",title="每个季节不同时间段的共享单车数量")
16
17sns.pointplot(data=shijianyuefen,x="时间",y="数量",hue="月份",ax=ax4)
18ax4.set(xlabel="时间",ylabel="数量",title="每月不同时间段的共享单车数量")
[Text(0,0.5,'数量'), Text(0.5,0,'时间'), Text(0.5,1,'每月不同时间段的共享单车数量')]
- 从图中得出阶段,时段对于共享单车使用数量有着较大的影响,在周一到周五通勤时,变化剧烈,具体时间段为5.00-10.00。16.00-20.00,在10.00-16.00之间平缓运行, 但是在12.00-13.00之间有一个小高峰,为午间休息时间。而且下午时间段要比上午时间段要高。但是周五的使用量在白天是略高于其他四天,但是晚上则是略低于 其他四天,这就以为这周五这一天白天人们出行时间多,而晚上则出行时间少。
- 在周末则是变换平缓,虽然通勤时间段没有工作日高,但是在9.00-16.00是要高于工作日的,并且变化平滑。
- 通过上面4个图可以得出,时段的曲线变化是基本不根据季节和月份来变化的,因此,时段对于共享单车数量的影响具有很强的规律和适用性。
4.4 查看不同时间注册用户与非注册用户的数据对比
1shijianyonghu=pd.DataFrame(bike.groupby("时间")["注册用户"].mean()).reset_index()
2shijianfeiyonghu=pd.DataFrame(bike.groupby("时间")["非注册用户"].mean()).reset_index()
1fig,ax1=plt.subplots()
2fig.set_size_inches(9,10)
3sns.pointplot(data=shijianfeiyonghu,x="时间",y="非注册用户",color="blue",ax=ax1,label="非注册用户")
4sns.pointplot(data=shijianyonghu,x="时间",y="注册用户",color="red",ax=ax1,label="注册用户")
5ax1.set(xlabel="时间",ylabel="数量",title="每个时间段非注册用户的数量")
6ax1.legend(loc="best")
No handles with labels found to put in legend.
<matplotlib.legend.Legend at 0xefb1be0>
1swz=pd.DataFrame(bike.groupby(["时间","星期"],sort=True)["注册用户"].mean()).reset_index()
2swfz=pd.DataFrame(bike.groupby(["时间","星期"],sort=True)["非注册用户"].mean()).reset_index()
1fig,(ax1,ax2)=plt.subplots(nrows=2,sharey=True)
2fig.set_size_inches(15,10)
3plt.ylim=([0,400])
4sns.pointplot(data=swz,x="时间",y="注册用户",hue="星期",ax=ax1)
5ax1.set(xlabel="时间",ylabel="数量",title="每周每个时间段注册用户的数量")
6sns.pointplot(data=swfz,x="时间",y="非注册用户",hue="星期",ax=ax2)
7ax2.set(xlabel="时间",ylabel="数量",title="每周时间段非注册用户的数量")
[Text(0,0.5,'数量'), Text(0.5,0,'时间'), Text(0.5,1,'每周时间段非注册用户的数量')]
- 如图所示,时段与注册用户的使用量具有明显的规律性,与通勤时间想吻合。而时段与未注册用户的使用量的关系与之相比则不够明显,但是也具有一定的 的规律性,在工作日的8.00-15.00之间,非注册用户的使用量缓慢上升,但是在周末,非注册用户的使用量变化则是与注册用户的使用量变化相同,都是在 8.00-14.00之间上升,在14.00-20.00下降,而且周日比周六的使用量更加少。
4.5 利用箱型图查看各时间单位上共享单车数量的变化
1fig,axes=plt.subplots(2,2)
2fig.set_size_inches(10, 10)
3sns.boxplot(data=bike,x="季节",y="数量",ax=axes[0][0])
4sns.boxplot(data=bike,x="时间",y="数量",ax=axes[0][1])
5sns.boxplot(data=bike,x="月份",y="数量",ax=axes[1][0])
6sns.boxplot(data=bike,x="星期",y="数量",ax=axes[1][1])
<matplotlib.axes._subplots.AxesSubplot at 0x10a48208>
- 从上图可以看出:季节,时间,月份对共享单车使用量的变化有一定想想,但是星期则没有大的影响。
4.6 不同天气因素对共享单车数量的影响
1sns.jointplot(data=bike,x="温度",y="数量")
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
<seaborn.axisgrid.JointGrid at 0xfbd57b8>
- 从上图看出,温度对数量的变化有一定的影响,在0-30度的时候,呈现的是正先关,但是超过30度,则呈现的是负相关。
1sns.jointplot(data=bike,x="湿度",y="数量")
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
<seaborn.axisgrid.JointGrid at 0x126b9fd0>
- 从上图看出,湿度对于数量有一定的负相关,湿度越高,数量越少。
1sns.jointplot(data=bike,x="天气",y="数量")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-138-b7651e10b8b4> in <module>()
----> 1 sns.jointplot(data=bike,x="天气",y="数量")
D:\anaconda\lib\site-packages\seaborn\axisgrid.py in jointplot(x, y, data, kind, stat_func, color, size, ratio, space, dropna, xlim, ylim, joint_kws, marginal_kws, annot_kws, **kwargs)
2249 marginal_kws.setdefault("kde", False)
2250 marginal_kws.setdefault("color", color)
-> 2251 grid.plot_marginals(distplot, **marginal_kws)
2252
2253 elif kind.startswith("hex"):
D:\anaconda\lib\site-packages\seaborn\axisgrid.py in plot_marginals(self, func, **kwargs)
1778 kwargs["vertical"] = False
1779 plt.sca(self.ax_marg_x)
-> 1780 func(self.x, **kwargs)
1781
1782 kwargs["vertical"] = True
D:\anaconda\lib\site-packages\seaborn\distributions.py in distplot(a, bins, hist, kde, rug, fit, hist_kws, kde_kws, rug_kws, fit_kws, color, vertical, norm_hist, axlabel, label, ax)
210 if hist:
211 if bins is None:
--> 212 bins = min(_freedman_diaconis_bins(a), 50)
213 hist_kws.setdefault("alpha", 0.4)
214 hist_kws.setdefault("normed", norm_hist)
D:\anaconda\lib\site-packages\seaborn\distributions.py in _freedman_diaconis_bins(a)
29 if len(a) < 2:
30 return 1
---> 31 h = 2 * iqr(a) / (len(a) ** (1 / 3))
32 # fall back to sqrt(a) bins if iqr is 0
33 if h == 0:
D:\anaconda\lib\site-packages\seaborn\utils.py in iqr(a)
346 """Calculate the IQR for an array of numbers."""
347 a = np.asarray(a)
--> 348 q1 = stats.scoreatpercentile(a, 25)
349 q3 = stats.scoreatpercentile(a, 75)
350 return q3 - q1
D:\anaconda\lib\site-packages\scipy\stats\stats.py in scoreatpercentile(a, per, limit, interpolation_method, axis)
1668 axis = 0
1669
-> 1670 return _compute_qth_percentile(sorted, per, interpolation_method, axis)
1671
1672
D:\anaconda\lib\site-packages\scipy\stats\stats.py in _compute_qth_percentile(sorted, per, interpolation_method, axis)
1711
1712 # Use np.add.reduce (== np.sum but a little faster) to coerce data type
-> 1713 return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval
1714
1715
TypeError: can't multiply sequence by non-int of type 'float'
1tianqi=pd.DataFrame(bike.groupby("天气")["数量"].mean()).reset_index()
2sns.barplot(data=tianqi,x="天气",y="数量")
<matplotlib.axes._subplots.AxesSubplot at 0x29cb2978>
1tianqi
| 天气 | 数量 | |
|---|---|---|
| 0 | 大雨,冰雹,雪,雾 | 164.000000 |
| 1 | 小雨,小雪,散云 | 118.846333 |
| 2 | 晴,少云 | 205.236791 |
| 3 | 薄雾,少云 | 178.955540 |
- 根据以上信息来进行判断,天气对于数量有有一定的影响,天气越恶劣,数量越少,但是大雨,冰雹天气的数量太小,只有一个,并不考虑。
1sns.jointplot(data=bike,x="风速",y="数量")
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
D:\anaconda\lib\site-packages\matplotlib\axes\_axes.py:6462: UserWarning: The 'normed' kwarg is deprecated, and has been replaced by the 'density' kwarg.
warnings.warn("The 'normed' kwarg is deprecated, and has been "
<seaborn.axisgrid.JointGrid at 0xfef1080>
- 总图中看出,温度对共享单车使用过的数量总体有一定的负相关,但是从相关系数上来看,则是正相关。我们进行细分的话,在小于15风速的时候,风速是正相关的,在大于15风速的情况下,风速是负相关的,两者都有局限性,因此,我们不能凭借风速来判断。