Python | 共享單車(chē)需求分析

01 目的

手里有一份A市近兩年來(lái)共享單車(chē)的租車(chē)數(shù)據(jù),字段豐富,可挖掘的東西蠻多的,真是讓人蠢蠢欲動(dòng)~~

那么今天我們就來(lái)挖一挖這份數(shù)據(jù),看看是哪些因素影響著人們的租車(chē)需求。

先給出數(shù)據(jù)各字段以及含義,先思考一下,如果是你,你會(huì)如何分析?

02 數(shù)據(jù)清洗

拿到任何數(shù)據(jù),第一件事是思考數(shù)據(jù)價(jià)值,思考你分析這份數(shù)據(jù)的目的,然后呢。

當(dāng)然是數(shù)據(jù)的觀察和清洗,不干凈的數(shù)據(jù)分析出來(lái)的結(jié)果你信么?

老套路,數(shù)據(jù)觀察3步走:

  1. 數(shù)據(jù)大小 (df.shape)
  2. 各字段數(shù)據(jù)類(lèi)型、缺失值 (df.info)
  3. head、tail數(shù)據(jù) (df.head)

可以看到,數(shù)據(jù)共10886行,12列,各字段均無(wú)缺失值(真是棒棒噠數(shù)據(jù)集吶)

再來(lái)看看數(shù)據(jù)表結(jié)構(gòu)

可以看到, datetime字段是日期格式,可以進(jìn)一步處理得到年月日時(shí)間周幾等信息;氣溫、體表溫度、濕度、風(fēng)速字段是連續(xù)變量,需要離散化處理后分析。

03 數(shù)據(jù)處理

剛才提到,datetime字段可以進(jìn)一步處理,得到年、月、日、時(shí)、周幾等信息,從而進(jìn)一步結(jié)合時(shí)間信息來(lái)分析A市共享單車(chē)需求。

下面我們針對(duì)日期型變量進(jìn)行處理。

主要思路:分裂split,切片

# 自定義函數(shù)獲取日期
def get_date(x):
    return x.split()[0]
# 對(duì)指定字段應(yīng)用自定義函數(shù)apply()
BikeData["date"]=BikeData.datetime.apply(get_date)
# 自定義函數(shù)獲取時(shí)間
def get_hour(x):
    hour=x.split()[1].split(":")[0]
    int_hour=int(hour) # 注意,這里的hour要轉(zhuǎn)換為數(shù)值型,因?yàn)樽址驮谂判驎r(shí)不按數(shù)值型排序規(guī)則來(lái)
    return int_hour

BikeData["hour"]=BikeData.datetime.apply(get_hour)

接下來(lái)我們想得到日期對(duì)應(yīng)的星期數(shù),思路是將字符串格式的日期通過(guò)datetime包中的strptime函數(shù)轉(zhuǎn)換為日期時(shí)間類(lèi)型,然后通過(guò).weekday獲取對(duì)應(yīng)的星期數(shù)

def get_weekday(x):
    dateStr=x.split()[0]
    dateDT=datetime.strptime(dateStr,"%Y/%m/%d")
    week_day=dateDT.weekday()
    return week_day

BikeData["weekday"]=BikeData.datetime.apply(get_weekday)
# 同樣的,自定義函數(shù)獲取日期對(duì)應(yīng)的月份
# 這里也可以使用切片+split的方法得到月份  x.split()[0].split("/")[1]
def get_month(x):
    dateStr=x.split()[0]
    dateDT=datetime.strptime(dateStr,"%Y/%m/%d")
    month=dateDT.month
    return month

BikeData["month"]=BikeData.datetime.apply(get_month)

好了,到這里,日期型變量處理完畢,現(xiàn)在的數(shù)據(jù)表結(jié)構(gòu)是這樣的,我們可以正式開(kāi)始挖掘分析了。

04 數(shù)據(jù)挖掘

4.1 相關(guān)性分析

我們先來(lái)看一看各字段之間的相關(guān)性,其中:

  • 相關(guān)系數(shù)介于-1,1之間
  • 負(fù)數(shù)表示負(fù)相關(guān),正數(shù)表示正相關(guān)
  • 絕對(duì)值越大,關(guān)系越強(qiáng)
# df.corr()計(jì)算dataframe中各字段的相關(guān)系數(shù)
correlation=BikeData[["season","holiday","workingday","weather","temp","atemp","humidity","windspeed","casual","registered","count"]].corr()

好像有點(diǎn)讓人眼花繚亂,那么我們就用熱地圖可視化相關(guān)系數(shù)。

fig=plt.figure(figsize=(12,12))
# 使用熱地圖(heat map)更直觀地展示系數(shù)矩陣情況
# vmax設(shè)定熱地圖色塊的最大區(qū)分值
# square設(shè)定圖片為正方形與否
# annot設(shè)定是否顯示每個(gè)色塊的系數(shù)值
sns.heatmap(correlation,vmax=1,square=True,annot=True)

可以看到,

  • count(租車(chē)人數(shù)):溫度、體感溫度與租車(chē)人數(shù)正相關(guān)-寒冷抑制租車(chē)需求;濕度與人數(shù)負(fù)相關(guān)-雨雪天氣抑制租車(chē)需求;注冊(cè)人數(shù)、非注冊(cè)人數(shù)與租車(chē)人數(shù)強(qiáng)正相關(guān)-轉(zhuǎn)化率問(wèn)題,用戶(hù)越多,租車(chē)需求越多;
  • registered(注冊(cè)用戶(hù)數(shù)):溫度高、工作日,刺激民眾成為注冊(cè)用戶(hù)-租車(chē)的需求可能更多的是非寒冷天氣的通勤;非注冊(cè)用戶(hù)與注冊(cè)用戶(hù)數(shù)強(qiáng)正相關(guān)-先試用再轉(zhuǎn)化,是一種商業(yè)模式;
  • temp(氣溫):氣溫和體溫強(qiáng)正相關(guān)-當(dāng)然氣溫越高體溫越高
  • season(季節(jié)):春季更干燥、低溫
4.2 可視化分析

接下來(lái)我們通過(guò)可視化來(lái)觀察租車(chē)需求的相關(guān)因素。

4.2.1 租車(chē)人數(shù)在各分類(lèi)變量下的箱線(xiàn)圖
  • 租車(chē)人數(shù)箱線(xiàn)圖(小時(shí)為單位)
  • 各月份租車(chē)人數(shù)箱線(xiàn)圖
  • 各星期數(shù)租車(chē)人數(shù)箱線(xiàn)圖
  • 各小時(shí)(0~23時(shí))租車(chē)人數(shù)箱線(xiàn)圖
  • 各季節(jié)租車(chē)人數(shù)箱線(xiàn)圖
  • 各天氣租車(chē)人數(shù)箱線(xiàn)圖
  • 節(jié)假日與否的租車(chē)人數(shù)箱線(xiàn)圖
  • 周末與否的租車(chē)人數(shù)箱線(xiàn)圖
# 繪制多圖
plt.style.use("ggplot")
fig=plt.figure(figsize=(16,24))

# 設(shè)置圖像大標(biāo)題
fig.suptitle("ShareBike Analysis",fontsize=16,fontweight="bold")

# 添加第一個(gè)子圖
ax1=fig.add_subplot(4,2,1)
sns.boxplot(data=BikeData,y="count")
plt.title("box plot on count")
plt.ylabel("Count")


# 添加第二個(gè)子圖
ax2=fig.add_subplot(4,2,2)
sns.boxplot(data=BikeData,x="month",y="count",hue="workingday")
ax2.set(ylabel="Count",xlabel="Month",title="box plot on count across month")


# 添加第三個(gè)子圖
ax3=fig.add_subplot(4,2,3)
sns.boxplot(data=BikeData,x="weekday",y="count")
ax3.set(ylabel="Count",xlabel="Weekday",title="box plot on count across weekday")


# 添加第四個(gè)子圖
ax4=fig.add_subplot(4,2,4)
sns.boxplot(data=BikeData,x="hour",y='count')

# 下面兩句代碼與ax2.set()效果一樣
# plt.title("box plot on count")
# plt.ylabel("Count")
ax4.set(ylabel="Count",xlabel="Hour",title="box plot on count aross hours")


# 添加第五個(gè)子圖
ax5=fig.add_subplot(4,2,5)
sns.boxplot(data=BikeData,x="season",y="count",hue="weather")
ax5.set(ylabel="Count",xlabel="Season",title="box plot on count across season")


# 添加第六個(gè)子圖
ax6=fig.add_subplot(4,2,6)
sns.boxplot(data=BikeData,x="weather",y="count")
ax6.set(ylabel="Count",xlabel="Weather",title="box plot on count across weather")


# 添加第七個(gè)子圖
ax7=fig.add_subplot(4,2,7)
sns.boxplot(data=BikeData,x="holiday",y="count")
ax7.set(ylabel="Count",xlabel="Holiday",title="box plot on count across holiday")


# 添加第八個(gè)子圖
ax8=fig.add_subplot(4,2,8)
sns.boxplot(data=BikeData,x="workingday",y="count")
ax8.set(ylabel="Count",xlabel="Workingday",title="box plot on count across workingday")

可以看到,

  • 每小時(shí)的租車(chē)人數(shù)中位數(shù)在150上下;
  • 寒冷季節(jié)(1,2,12月),工作日租車(chē)人數(shù)高于非工作日,看來(lái)寒冷季節(jié)租車(chē)以通勤為主,那么冷的天,周末當(dāng)然是窩在家里啦;溫暖、涼爽季節(jié)(5-11月),非工作日租車(chē)人數(shù)高于工作日,看來(lái)這些季節(jié)租車(chē)以游玩為主,春暖花開(kāi)、夏日蟬鳴、秋高氣爽,當(dāng)然要騎車(chē)車(chē)出去玩耍啦;
  • 租車(chē)高峰時(shí)段為早上的7、8、9點(diǎn)和下午的5、6、7點(diǎn),正好是上下班高峰期;
  • 春季租車(chē)人數(shù)少,可能是乍暖還寒,人們不愿意出門(mén),并且這段時(shí)間正好趕上中國(guó)春節(jié),大城市人口外流,租車(chē)需求減少;
  • 天氣越好,租車(chē)的人越多,暴雨暴雪一般沒(méi)有人租車(chē)
4.2.2 連續(xù)變量與租車(chē)人數(shù)的關(guān)系
# 連續(xù)變量離散化,使用pd.cut分為5段
BikeData["temp_band"]=pd.cut(BikeData["temp"],4)
BikeData["humidity_band"]=pd.cut(BikeData["humidity"],5)
BikeData["windspeed_band"]=pd.cut(BikeData["windspeed"],5)

連續(xù)變量離散化后,我們來(lái)看看氣溫、濕度、天氣對(duì)租車(chē)人數(shù)的影響吧

# 將季節(jié)1234對(duì)應(yīng)到春夏秋冬(使用映射函數(shù).map)
BikeData["season_word"]=BikeData["season"].map({1:"Spring",2:"Summer",3:"Autumn",4:"Winter"})

sns.FacetGrid(data=BikeData,row="humidity_band",aspect=2.2).\
map(sns.barplot,"temp_band","count","season_word",hue_order=["Spring","Summer","Autumn","Winter"],palette="deep",ci=None).\
add_legend()
plt.xticks(rotation=60)

可以看到,

  • 氣溫低于10,高于30度,租車(chē)人數(shù)較少-太冷太熱都會(huì)抑制租車(chē)需求
  • 空氣濕度越高,租車(chē)人數(shù)越少-干爽的天氣騎車(chē)比較舒適
  • 干燥的夏天、濕潤(rùn)的冬天,秋天是租車(chē)需求比較旺盛的時(shí)期
4.2.3 不同季節(jié)下,各小時(shí)段的租車(chē)人數(shù)情況
plt.style.use("ggplot")

sns.FacetGrid(data=BikeData,size=6,aspect=1.5).\
map(sns.pointplot,"hour","count","season_word",hue_order=["Spring","Summer","Autumn","Winter"],paletter="deep",ci=None).\
add_legend()

可以看到,

  • 不論季節(jié),每天早晨7-9點(diǎn),傍晚16-19點(diǎn)是租車(chē)高峰期,分別在8點(diǎn)和17點(diǎn)達(dá)到時(shí)段峰值
  • 工作時(shí)段的租車(chē)人數(shù)處于一天中的中間水平,夜幕降臨后,租車(chē)人數(shù)逐漸減少-夜晚寒冷、陰暗,騎車(chē)不便利
  • 春季用車(chē)人數(shù)總體較少,夏秋季最多
4.2.4 工作日與否,各小時(shí)租車(chē)人數(shù)情況
sns.FacetGrid(data=BikeData,size=6,aspect=1.5).\
map(sns.pointplot,"hour","count","workingday",hue_order=[1,0],paletter="deep",ci=None).\
add_legend()

可以看到,

  • 是否是工作日,對(duì)于用車(chē)高峰時(shí)段的影響非常大
  • 工作日的租車(chē)高峰時(shí)段非常明顯,處于7-9點(diǎn),16-19點(diǎn)-通勤為主
  • 非工作日租車(chē)高峰時(shí)段特征較為平緩,從上午10點(diǎn)租車(chē)人數(shù)逐漸增多,到晚上8點(diǎn)后,租車(chē)人數(shù)回到低峰水平-非工作日主要用于休閑代步、短途旅游等(大家起床都很遲嘛)
4.2.5 不同天氣情況下,各月份的租車(chē)人數(shù)
BikeData["weather_word"]=BikeData["weather"].map({1:"sunny",2:"foggy",3:"rainy",4:"stormy"})

# 數(shù)據(jù)透視表呈現(xiàn)
BikeData[["count","month","weather_word"]].pivot_table(values="count",index="month",columns="weather_word",aggfunc="mean")

# 可視化呈現(xiàn)
sns.FacetGrid(data=BikeData,size=6,aspect=1.5).\
map(sns.pointplot,"month","count","weather_word",hue_order=["sunny","foggy","rainy","stromy"],paletter="deep",ci=None).\
add_legend()

可以看到,

  • 天氣越好,租車(chē)人數(shù)越多
  • 5-10月租車(chē)人數(shù)最多-與天氣、氣候、營(yíng)銷(xiāo)宣傳都有關(guān)系

05 預(yù)告

今天我們針對(duì)一份上萬(wàn)行的共享單車(chē)數(shù)據(jù)進(jìn)行挖掘分析,我們做了相關(guān)性分析以及可視化分析,知道了是哪些因素在影響A市的租車(chē)需求。

這份數(shù)據(jù)還有很多地方可以挖掘,比如預(yù)測(cè)某個(gè)特定條件下的租車(chē)人數(shù)。

這就需要結(jié)合機(jī)器學(xué)習(xí)的方法,讓機(jī)器自己去擬合最佳的權(quán)重系數(shù),這是我們后面將要研究的主要課題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容