本文是就一套經典的共享單車租用情況的數據集做的數據分析與探索。本次對於數據的處理是在和鯨工作台完成
數據來源及描述
本次數據來自與和鯨社區,采用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(【懷念單車給你我,唯一有過的擁抱】共享單車數據分析)