0 前言
Hi,大家好,這里是丹成學(xué)長,今天向大家介紹一個學(xué)長做的數(shù)據(jù)分析項目,基于大數(shù)據(jù)的共享單車數(shù)據(jù)分析
畢設(shè)幫助,開題指導(dǎo),資料分享,疑問解答(見文末)
?? 選題指導(dǎo), 項目分享:見文末
1 項目背景
公共交通工具的“最后一公里”是城市居民出行采用公共交通出行的主要障礙,也是建設(shè)綠色城市、低碳城市過程中面臨的主要挑戰(zhàn)。
共享單車(自行車)企業(yè)通過在校園、地鐵站點、公交站點、居民區(qū)、商業(yè)區(qū)、公共服務(wù)區(qū)等提供服務(wù),完成交通行業(yè)最后一塊“拼圖”,帶動居民使用其他公共交通工具的熱情,也與其他公共交通方式產(chǎn)生協(xié)同效應(yīng)。
共享單車是一種分時租賃模式,也是一種新型綠色環(huán)保共享經(jīng)濟(jì)。自2014年ofo首次提出共享單車概念,至今已陸續(xù)產(chǎn)生了25個共享單車品牌,與傳統(tǒng)的有樁借還自行車相比,無樁的共享單車自由度更高,廣受用戶好評。
本次分析擬取2017年5月中旬某共享單車在北京地區(qū)的車輛訂單數(shù)據(jù),從時間、空間、頻次三個維度進(jìn)行分析,對該品牌共享單車的發(fā)展方向提出改善性意見。
2 項目分析思維導(dǎo)圖
3 項目分析具體步驟
3.1 讀取數(shù)據(jù)
from geopy.geocoders import BaiduV3
from geopy import distance
import geohash as gh
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pyecharts.charts import *
from pyecharts import options as opts
import datetime
%matplotlib inline
fpath="../data/shared-bakes/train.csv"
df_shared_bakes=pd.read_csv(fpath,encoding="gbk")
df_shared_bakes.head()
3.2 數(shù)據(jù)分析
3.1.1 數(shù)據(jù)預(yù)處理——每日使用量分析
df_shared_bakes_time_sorted=df_shared_bakes.sort_values(by="starttime")
df_shared_bakes_time_sorted.head()
#完整數(shù)據(jù)的時間跨度為2017-5-10至2017-5-24,歷時15天
early=df_shared_bakes_time_sorted.iloc[0,:]
last=df_shared_bakes_time_sorted.iloc[-1,:]
print(early.starttime)
print(last.starttime)
df_shared_bakes_time_in_range=df_shared_bakes_time_sorted.loc[df_shared_bakes_time_sorted["starttime"]<"2017-05-17",:]
df_shared_bakes_time_in_range.iloc[-1,:]
#提取連續(xù)7天數(shù)據(jù)的1%用于時間維度的分析
df_shared_bakes_data_used=df_shared_bakes_time_in_range.loc[df_shared_bakes_time_in_range.index%100==0,:]
df_shared_bakes_data_used.info()
#2017-05-10是星期三
#對比7天內(nèi)每天的用戶總量,分析工作日與周末的使用量是否存在差異
df_used_by_date=df_shared_bakes_data_used
a=df_used_by_date["starttime"].str.split(" ",expand=True)
#a
df_used_by_date.loc[:,"startdate"]=a.loc[:,0]
df_used_by_date.loc[:,"startetime"]=a.loc[:,1]
#df_used_by_date.head()
s_used_by_date=df_used_by_date.groupby("startdate").count()["userid"]
s_used_by_date
3.1.2 連續(xù)7天的單日使用分析結(jié)論
- 工作日相較于周末使用量更多
- 分別比較工作日與周末的使用量,整體趨勢為穩(wěn)步增長趨勢
#工作日比周末(13,14日)的使用量更多
bar_used_by_date=(Bar()
.add_xaxis(list(s_used_by_date.index))
.add_yaxis("每日單車使用次數(shù)/100",list(s_used_by_date))
.set_global_opts(
title_opts={"text":"連續(xù)7天的單日使用量統(tǒng)計","subtext":"取連續(xù)7天數(shù)據(jù)的1%進(jìn)行統(tǒng)計"})
)
bar_used_by_date.render_notebook()
#工作日平均每天的使用量占比約為54.23%,周末平均每天使用量占比45.77%
workday_used_mean=s_used_by_date[s_used_by_date.index.isin(["2017-05-10","2017-05-11","2017-05-12","2017-05-15","2017-05-16"])].sum()/5
weekend_used_mean=s_used_by_date[s_used_by_date.index.isin(["2017-05-13","2017-05-14"])].sum()/2
#print(workday_used_mean)
#print(weekend_used_mean)
weekend_pct=round(weekend_used_mean*100/(weekend_used_mean+workday_used_mean),2)
workday_pct=round(workday_used_mean*100/(weekend_used_mean+workday_used_mean),2)
pie_used_data=[["workday "+str(workday_pct)+"%",workday_used_mean],["weekend "+str(weekend_pct)+"%",weekend_used_mean]]
pie_used=(Pie()
.add("",pie_used_data,center=["35%","50%"],radius=[0,175])
.set_global_opts(title_opts=opts.TitleOpts(title="工作日與周末平均使用量占比統(tǒng)計")))
pie_used.render_notebook()
#s_used_by_date.sum()
#s_used_by_date.sum()
3.1.3 數(shù)據(jù)預(yù)處理——每日不同時間段的使用量分析
#提取小時信息,用于每日不同時間段的使用量分析
df_used_by_date.loc[:,"hour"]=df_used_by_date["startetime"].str.slice(0,2)
#df_used_by_date.loc[:,"startetime"]
df_used_by_date.head()
#將數(shù)據(jù)分為7個單日,分布分析每日不同時間段的使用量
Wednesday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-10",:]
Thursday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-11",:]
Friday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-12",:]
Saturday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-13",:]
Sunday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-14",:]
Monday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-15",:]
Tuesday=df_used_by_date.loc[df_used_by_date.startdate=="2017-05-16",:]
Wednesday_used=Wednesday.groupby("hour").count()["userid"]
Thursday_used=Thursday.groupby("hour").count()["userid"]
Friday_used=Friday.groupby("hour").count()["userid"]
Saturday_used=Saturday.groupby("hour").count()["userid"]
Sunday_used=Sunday.groupby("hour").count()["userid"]
Monday_used=Monday.groupby("hour").count()["userid"]
Tuesday_used=Tuesday.groupby("hour").count()["userid"]
#對比每一天不同時間的使用量,分析是否存在有規(guī)律的使用峰值等特征
#工作日與周末分布有不同的分布規(guī)律,分別分析
Line_used_by_time=(Line()
.add_xaxis(list(Wednesday_used.index))
.add_yaxis("Wednesday",Wednesday_used)
.add_yaxis("Thursday",Thursday_used)
.add_yaxis("Friday",Friday_used)
.add_yaxis("Saturday",Saturday_used)
.add_yaxis("Sunday",Sunday_used)
.add_yaxis("Monday",Monday_used)
.add_yaxis("Tuesday",Tuesday_used)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="連續(xù)7天單日不同時間段使用量統(tǒng)計",subtitle="取連續(xù)7天數(shù)據(jù)的1%進(jìn)行統(tǒng)計"),
legend_opts=opts.LegendOpts(pos_left="right"))
)
Line_used_by_time.render_notebook()
3.1.4 每日不同時間段使用量分析結(jié)論
- 工作日早晚各有一個峰值,中午12點有一個小峰值,說明工作日的單車使用時間符合通勤高峰時間規(guī)律,工作日的使用場景以通勤為主,還伴有部分午餐時間的使用
- 周末在8點至21點區(qū)間內(nèi)使用量平緩分布,中午11至12點、晚5點至7點各有一個小高峰,說明周末的單車使用時間與午餐、晚餐時間相關(guān),即周末的使用場景以休閑、聚餐為主
- 結(jié)合前述單日總使用量的對比,通勤需求產(chǎn)生的使用量更大,可能產(chǎn)生潮汐現(xiàn)象(后續(xù)具體分析)
- 可以選擇工作日非高峰時段或周末進(jìn)行單車維修、保養(yǎng)等工作
#對比工作日與周末不同時間的使用量,分析分布規(guī)律
Line_used_by_time_new=(Line()
.add_xaxis(list(Weekend_used.index))
.add_yaxis("Weekend",Weekend_used,
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
.add_yaxis("Workday",Workday_used,
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False))
)
Line_used_by_time_new.render_notebook()
3.1.5 數(shù)據(jù)預(yù)處理——騎行距離的分析
df_used_by_date=df_used_by_date.reset_index(drop=True)
df_used_by_date.head()
#當(dāng)前位置數(shù)據(jù)采用geohash編碼方式,geohash編碼長度為7位
#解碼后發(fā)現(xiàn)經(jīng)緯度在小數(shù)點后兩位時,geohash編碼的第7位無法有效區(qū)分
#因此距離小于850m時,無法明確計算出距離,統(tǒng)一用0值填充
s_series=df_used_by_date.loc[:,"geohashed_start_loc"]
e_series=df_used_by_date.loc[:,"geohashed_end_loc"]
for i in df_used_by_date.index:
s=gh.decode(s_series[i])
e=gh.decode(e_series[i])
s_loc=str(float(s[0]))+","+str(float(s[1]))
e_loc=str(float(e[0]))+","+str(float(e[1]))
df_used_by_date.loc[i,"起始緯度"]=float(s[0])
df_used_by_date.loc[i,"起始經(jīng)度"]=float(s[1])
df_used_by_date.loc[i,"結(jié)束緯度"]=float(e[0])
df_used_by_date.loc[i,"結(jié)束經(jīng)度"]=float(e[1])
df_used_by_date.loc[i,"起始點距離"]=distance.distance(s,e).km
if i%1000==0:
print(f'{round(i*100/(df_used_by_date.index.stop-1),5)}%')
elif i==df_used_by_date.index.stop-1:
print("100%")
df_used_by_date.head(10)
#工作日與周末的分布情況相似,大部分用戶的騎行距離都小于1.4km
dis_10=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-10","起始點距離"],2)
dis_11=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-11","起始點距離"],2)
dis_12=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-12","起始點距離"],2)
dis_13=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-13","起始點距離"],2)
dis_14=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-14","起始點距離"],2)
dis_15=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-15","起始點距離"],2)
dis_16=round(df_used_by_date.loc[df_used_by_date.startdate=="2017-05-16","起始點距離"],2)
box=(Boxplot()
.add_xaxis(["2017-05-10","2017-05-11","2017-05-12","2017-05-13","2017-05-14","2017-05-15","2017-05-16"])
.add_yaxis("",Boxplot.prepare_data([dis_10,dis_11,dis_12,dis_13,dis_15,dis_15,dis_16]))
.set_global_opts(title_opts=opts.TitleOpts(title="用戶騎行距離統(tǒng)計")))
box.render_notebook()
#騎行距離不超過1km的用戶占比過半
df_used_by_date["起始點int值"]=df_used_by_date.起始點距離.astype(int)
dis_grouped=df_used_by_date.groupby("起始點int值").count()["userid"]
pie_dis_x=list(str(i)+"-"+str(i+1)+" km" for i in dis_grouped.index)
dis_data=list(list(z) for z in zip(pie_dis_x,dis_grouped))
dis_data[0][0]="小于1 km"
pie_dis=(Pie()
.add("",dis_data,center=["35%", "60%"],radius=[0, 175])
.set_global_opts(title_opts=opts.TitleOpts(title="騎行距離比例分布",pos_bottom="83%"))
)
pie_dis.render_notebook()
3.1.6 數(shù)據(jù)預(yù)處理——高峰期單車遷移情況分析
#df_used_by_date.起始緯度.min()——26.14
#df_used_by_date.起始緯度.max()——40.3
#df_used_by_date.起始經(jīng)度.min()——114.15
#df_used_by_date.起始經(jīng)度.max()——121.52
#df_used_by_date.結(jié)束緯度.min()——26.13
#df_used_by_date.結(jié)束緯度.max()——40.3
#df_used_by_date.結(jié)束經(jīng)度.min()——114.14
#df_used_by_date.結(jié)束經(jīng)度.max()——121.51
#提取7-8點時間段內(nèi)所有被使用的單車的起點位置和終點位置
df_hour_7=df_used_by_date.loc[df_used_by_date.hour=="07",:]
start_point_7=df_hour_7.groupby(["起始經(jīng)度","起始緯度"]).count()["orderid"]
start_point_7=start_point_7.reset_index(drop=False)
t=zip(start_point_7["起始經(jīng)度"],start_point_7["起始緯度"],start_point_7["orderid"])
start_loc_7=[]
for z in t:
#print(z)
start_loc_7.append(list(z))
end_point_7=df_hour_7.groupby(["結(jié)束經(jīng)度","結(jié)束緯度"]).count()["orderid"]
end_point_7=end_point_7.reset_index(drop=False)
t=zip(end_point_7["結(jié)束經(jīng)度"],end_point_7["結(jié)束緯度"],end_point_7["orderid"])
end_loc_7=[]
for z in t:
#print(z)
end_loc_7.append(list(z))
#提取8-9點時間段內(nèi)所有被使用的單車的起點位置和終點位置
df_hour_8=df_used_by_date.loc[df_used_by_date.hour=="08",:]
start_point_8=df_hour_8.groupby(["起始經(jīng)度","起始緯度"]).count()["orderid"]
start_point_8=start_point_8.reset_index(drop=False)
t=zip(start_point_8["起始經(jīng)度"],start_point_8["起始緯度"],start_point_8["orderid"])
start_loc_8=[]
for z in t:
#print(z)
start_loc_8.append(list(z))
end_point_8=df_hour_8.groupby(["結(jié)束經(jīng)度","結(jié)束緯度"]).count()["orderid"]
end_point_8=end_point_8.reset_index(drop=False)
t=zip(end_point_8["結(jié)束經(jīng)度"],end_point_8["結(jié)束緯度"],end_point_8["orderid"])
end_loc_8=[]
for z in t:
#print(z)
end_loc_8.append(list(z))
#將7-8點時間段內(nèi)的點起始位置分布繪制為兩張圖
bar_3D_start_7=(Bar3D()
.add("",
start_loc_7)
.set_global_opts(
title_opts=opts.TitleOpts(title="7-8點單車遷移情況統(tǒng)計",subtitle="7-8點單車起始位置分布"),
visualmap_opts=opts.VisualMapOpts(
max_=8,
min_=5,
range_color=[
"#313695",
"#4575b4",
"#74add1",
"#abd9e9",
"#e0f3f8",
"#ffffbf",
"#fee090",
"#fdae61",
"#f46d43",
"#d73027",
"#a50026",
],
)
))
bar_3D_end_7=(Bar3D()
.add("",
end_loc_7)
.set_global_opts(
title_opts=opts.TitleOpts(title="",subtitle="7-8點單車結(jié)束位置分布"),
visualmap_opts=opts.VisualMapOpts(
max_=8,
min_=5,
range_color=[
"#313695",
"#4575b4",
"#74add1",
"#abd9e9",
"#e0f3f8",
"#ffffbf",
"#fee090",
"#fdae61",
"#f46d43",
"#d73027",
"#a50026",
],
)))
3.1.7 數(shù)據(jù)預(yù)處理——用戶使用頻次分析
user_frequency=pd.DataFrame(df_shared_bakes_time_in_range.groupby("userid").count()["orderid"])
user_frequency=user_frequency.reset_index()
pie_user_frequency_data=user_frequency.groupby("orderid").count()["userid"]
more_than_10=pie_user_frequency_data[pie_user_frequency_data.index>10].sum()
pie_user_frequency_data=pie_user_frequency_data[:11]
pie_user_frequency_data[11]=more_than_10
pie_user_frequency_data=list(list(z) for z in zip(pie_user_frequency_data.index,pie_user_frequency_data))
pie_user_frequency_data[10][0]="大于10次"
date=df_shared_bakes_time_in_range["starttime"].str.slice(0,10)
df_shared_bakes_time_in_range.loc[:,"startdate"]=date
df_shared_bakes_time_in_range.head()
#date
user_frequency_weekend=pd.DataFrame(df_shared_bakes_time_in_range.loc[df_shared_bakes_time_in_range.startdate.isin(weekend),:].groupby("userid").count()["orderid"])
user_frequency_workday=pd.DataFrame(df_shared_bakes_time_in_range.loc[df_shared_bakes_time_in_range.startdate.isin(workday),:].groupby("userid").count()["orderid"])
user_frequency_weekend=user_frequency_weekend.reset_index()
user_frequency_workday=user_frequency_workday.reset_index()
pie_user_frequency_data_weekend=user_frequency_weekend.groupby("orderid").count()["userid"]
pie_user_frequency_data_workday=user_frequency_workday.groupby("orderid").count()["userid"]
more_than_10_weekend=pie_user_frequency_data_weekend[pie_user_frequency_data_weekend.index>10].sum()
more_than_10_workday=pie_user_frequency_data_workday[pie_user_frequency_data_workday.index>10].sum()
pie_user_frequency_data_weekend=pie_user_frequency_data_weekend[:11]
pie_user_frequency_data_workday=pie_user_frequency_data_workday[:11]
pie_user_frequency_data_weekend[11]=more_than_10_weekend
pie_user_frequency_data_workday[11]=more_than_10_workday
pie_user_frequency_data_weekend=list(list(z) for z in zip(pie_user_frequency_data_weekend.index,pie_user_frequency_data_weekend))
pie_user_frequency_data_workday=list(list(z) for z in zip(pie_user_frequency_data_workday.index,pie_user_frequency_data_workday))
pie_user_frequency_data_weekend[10][0]="大于10次"
pie_user_frequency_data_workday[10][0]="大于10次"
-
一周內(nèi)用戶的使用次數(shù)大量分布在10次以下,50%的用戶使用次數(shù)為4次及以下
-
周末期間用戶使用單車的次數(shù)普遍分布在3次及以下
-
工作日期間用戶使用共享單車的次數(shù)普遍分布在5次及以下,使用3次及以下的用戶占比近一半
-
工作日期間的用戶使用頻次有較大提升空間,通勤時段用戶有大量使用需求,但總體來看使用頻次仍偏低,考慮改進(jìn)兩個因素
-
因素一 高峰時段的車輛分布情況,是否因為高峰時段車輛數(shù)量不足,導(dǎo)致用戶無法使用到單車文章來源:http://www.zghlxwxcb.cn/news/detail-860178.html
-
因素二 用戶粘性差,是否用戶對本品牌的單車選擇傾向性低,可以考慮加大月卡等套餐的推廣力度,或提升本品牌單車品質(zhì)
*工作日期間使用單車次數(shù)6次及以上的用戶為高粘性用戶,占比約30%文章來源地址http://www.zghlxwxcb.cn/news/detail-860178.html
4 項目總結(jié)
4.1 分析明確了共享單車的使用場景:
- 工作日早晚高峰的通勤需求和午餐時間部分用戶外出用餐需求
- 周末午餐、晚餐時間外出就餐需求,以及白天無明顯峰值的外出需求
- 短距離騎行(1.4公里內(nèi))
4.2 改善性意見:
- 工作日高峰期時間段有明顯的潮汐現(xiàn)象,可以提前增加高用車需求區(qū)域的單車投放量
- 用戶使用頻次有提升空間,考慮到工作日的通勤需求,五個工作日期間有近50%的用戶使用頻次不超過三次,用戶粘性較差,可以推廣月卡或優(yōu)惠套餐等進(jìn)一步提升用戶粘性
5 最后-畢設(shè)幫助
到了這里,關(guān)于畢業(yè)設(shè)計 基于大數(shù)據(jù)的共享單車數(shù)據(jù)分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!