美国旧金山共享单车数据分析
美国共享单车数据分析
- 一、数据说明
- 二、数据清洗
- 1.空值删除
- 2.数据类型转化
- 3.统计值概览
- 4.异常数据
- 5.数据筛选
- 6.新增小时、周、月纬度
- 三、探索性分析
- 1.数据概览
- 2.数据异常分析
- 3.bike_plan与会员关系
- 4.小时、周、月纬度分析
- 5.高峰时间骑行数据
- 6.订阅会员分析
- 7.工作日与周末出行情况
- 8.站点热度分析
- 四、结论
一、数据说明
本次分析的数据是美国旧金山地区共享单车的骑行信息,时间范围2018-01-01至2018-12-23,点击可进行下载csv文件。
数据约180万条,共14个特征。
骑行秒数 | 开始时间 | 结束时间 | 开始站点ID | 开始站点名称 | 开始站点纬度 | 开始站点经度 | 结束站点ID | 结束站点名称 | 结束站点纬度 | 结束站点经度 | 车辆ID | 用户类型 | 计划参与 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
duration_sec | start_time | end_time | start_station_id | start_station_name | start_station_latitude | start_station_longitude | end_station_id | end_station_name | end_station_latitude | end_station_longitude | bike_id | user_type | bike_share_for_all_trip |
本次主要使用Pandas、matplotlib、folium库进行分析与可视化
二、数据清洗
# 导入常用库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import folium # 地图可视化
from folium.plugins import HeatMap
%matplotlib inline
path = '/Users/valkyrja/Documents/dataanalysis/taobao/2018-baywheels-tripdata.csv'
data = pd.read_csv(path)
data.info(null_counts = True) #概览数据类型与空值的情况
- 共1863721行数据
- 14个特征
- 开始时间、结束时间数据类型需要调整为datetime
- 开始结束站点ID、bikeID视情况调整为字符串类型
- 开始结束站点的ID和名称列,每个特征存在约1万个缺失值
# 进一步观察缺失值情况(每个特征确实11771条数据)
data.isna().sum()# 查看是否有重复数据(无重复数据,无须去重操作)
data.duplicated().sum()
每个特征约1万条确实值,进行删除操作,不影响整体数据。
1.空值删除
# 删除缺失值的行
data.dropna(subset = ['start_station_id', 'start_station_name', 'end_station_id', 'end_station_name'], inplace = True)
2.数据类型转化
# 开始结束时间数据类型调整为datetime类型
for i in ['start_time', 'end_time']:data[i] = pd.to_datetime(data[i])
# 站点id、车辆id调整为字符串类型
for m in ['start_station_id', 'end_station_id', 'bike_id']:data[m] = data[m].astype('int').astype('str')
3.统计值概览
# 对骑行时间进行统计值概览
round(data['duration_sec'].describe(), 2)
这里发现了问题,75%的骑行时间小于870秒(约15分钟),最大值为86366秒(约24个小时),最大时间有点反常。
4.异常数据
# 找数据观察一下
data[data['duration_sec'] > 86300]
- 根据数据发现,记录时间是没有问题的
- 但起止站点是一样的,经纬度也相同
- 推断:车辆故障或用户忘记关闭记录锁
# 查看99%骑行时间大小
num = int(data.shape[0] * 0.99)
data['duration_sec'].sort_values(ascending = True).iloc[:num].tail(10)
99%骑行时间是在5496秒(约1.5小时)以下,根据实际共享单车骑行时间判断,2小时以下为正常骑行的标准,对2小时以上的骑行数据判定为异常数据。
5.数据筛选
# 筛选出2小时及以下骑行时间的数据
data_2 = data[data['duration_sec'] <= 7200]# 简单看一下骑行数据的分布
plt.hist(data_2['duration_sec'], bins = 50)
plt.show()
筛选数据后,约90%数据仍在2000秒(30分钟)以内。
6.新增小时、周、月纬度
data_2['hour'] = data_2['start_time'].dt.hour
data_2['week'] = data_2['start_time'].dt.dayofweek
data_2['week'] = data_2['start_time'].dt.month# 顺便重命名共享计划的列名为 'bike_plan',原名太长了
data.rename(columns = {'bike_share_for_all_trip':'bike_plan'}, inplace = True)
三、探索性分析
1.数据概览
# 共计1838703行数据
data_2.shape
# 共计4852辆共享单车
data_2['bike_id'].nunique()
# 站点共计331个
data_2['start_station_id'].nunique()
data_2['end_station_id'].nunique()
# 订阅会员发生1572041次的骑行记录,普通用户发生266662次骑行记录
data_2['user_type'].value_counts()
订阅会员数量约占85%,普通用户约占15%
# bike_plan计划用户发生160898次骑行记录。
data_2['bike_plan'].value_counts()
# 骑行时间统计值观察
round(data_2['duration_sec'].describe(), 2)
2.数据异常分析
- 车辆故障,当时无法关锁
- 用户遗忘关锁
- 遗忘关锁,他人接力骑行
- 订阅用户故意不关锁
- bike_plan用户故意不关锁
# 首先看一下起终点相同的数据
de = data[data['start_station_id'] == data['end_station_id']]
de.shape
起终点相同的数据约5千,车辆在同一个站点在某个时间点开始计时,然后在另外一个时间点关闭计时,是否一开始车辆就未关锁,直到系统自动关锁。
# 查看异常数据与bike_plan的关系
de['bike_plan'].value_counts()
非bike_plan用户占比约83%。
# 异常数据与用户类型的关系
de['user_type'].value_counts()
订阅用户约占55%,普通用户占44%。但是数据相关性并不明显,无法直接判断。
3.bike_plan与会员关系
data_2[data_2['bike_plan'] == 'Yes'].shape
bike_plan的数据约16万条
# bike_plan为真的情况下,会员的数量
data_2[data_2['bike_plan'] == 'Yes']['user_type'].value_counts()
bike_plan为真,用户为订阅用户,订阅会员骑行记录中bike_plan计划记录约占10%。
4.小时、周、月纬度分析
# 分别按小时、周、月的纬度对骑行时间分组求和
gbhs = data_2.groupby(by = ['hour'], as_index = False).agg({'duration_sec':'sum'})
gbws = data_2.groupby(by = ['week'], as_index = False).agg({'duration_sec':'sum'})
gbms = data_2.groupby(by = ['month'], as_index = False).agg({'duration_sec':'sum'})
# 对求和数据进行可视化
plt.figure(figsize = (18, 6))plt.subplot(131)
h_sec = gbhs['duration_sec'] / 3600
plt.plot(gbhs['hour'], h_sec)
plt.xticks(list(range(0, 24)))
plt.title('hour')plt.subplot(132)
w_sec = gbws['duration_sec'] / 3600
plt.plot(gbws['week'], w_sec)
plt.title('week')
plt.xticks(list(range(0, 7)))plt.subplot(133)
m_sec = gbms['duration_sec'] / 3600
plt.plot(gbms['month'], m_sec)
plt.xticks(list(range(1, 13)))
plt.title('month')plt.show()
- 小时纬度:凌晨、夜间骑行时间低,白天骑行时间高。
- 小时纬度:推测早晚上班高峰用户集中使用,7点-9点,17点-19点。
- 周纬度:工作日使用时常高,周末较低。
- 月纬度:5月-10月车辆骑行时间高。
推测工作通勤、天气气温与车辆使用时常有很大的相关性。10月后骑行时间明显降低,推测收入将随之降低,是否可以在这个节点推出优惠的冬季订阅套餐,从而提升冬季较低的收入。
# 分别按小时、周、月的纬度对骑行时间分组求mean
gbhm = data_2.groupby(by = ['hour'], as_index = False).agg({'duration_sec':'mean'})
gbwm = data_2.groupby(by = ['week'], as_index = False).agg({'duration_sec':'mean'})
gbmm = data_2.groupby(by = ['month'], as_index = False).agg({'duration_sec':'mean'})
# 对以上数据进行可视化
plt.figure(figsize = (18, 6))plt.subplot(131)
h_sec = gbhm['duration_sec'] / 3600
plt.plot(gbhm['hour'], h_sec)
plt.xticks(list(range(0, 24)))
plt.title('hour')plt.subplot(132)
w_sec = gbwm['duration_sec'] / 3600
plt.plot(gbwm['week'], w_sec)
plt.title('week')
plt.xticks(list(range(0, 7)))plt.subplot(133)
m_sec = gbmm['duration_sec'] / 3600
plt.plot(gbmm['month'], m_sec)
plt.xticks(list(range(1, 13)))
plt.title('month')plt.show()
- 小时纬度:7点-9点,17点-18点,车辆平均骑行时间小于20分钟。
- 周纬度:周一至周五,平均骑行时常小于20分钟,周末在25分钟浮动。
- 月纬度:5月至9月骑行时间在20分钟以上,8月突出降低。
推测:车辆平均使用时间在30分钟以内,与通勤距离有关。8月气温较高,骑车感受不佳,车辆骑行时间降低,网上搜索2018年美国7、8月历史最高气温为30度。
5.高峰时间骑行数据
# 通勤高峰车辆使用次数
data_2[data_2['hour'].isin([7, 9, 17, 19])].shape
h_s = data_2[data_2['hour'].isin([7, 9, 17, 19])]['duration_sec'].sum()
all_sum = data_2['duration_sec'].sum()
7-9点, 17-19点期间共发生了约58万次的骑行记录,约占全年骑行记录的32%,骑行时常约占全年的30%
6.订阅会员分析
Sub_sec = data_2[(data_2['hour'].isin([7, 9, 17, 19])) & (data_2['user_type'] == 'Subscriber') & (data_2['bike_plan'] == 'No')]['duration_sec'].sum()
订阅会员年骑行时常为295442648秒,约占全年使用时间的23%。
# 订阅会员与普通用户的骑行时间可视化
C_dur = data_2[data_2['user_type'] == 'Customer']['duration_sec'] / 3600
Su_dur = data_2[data_2['user_type'] == 'Subscriber']['duration_sec'] / 3600plt.hist(C_dur, bins = 50, label = 'C_dur', color = 'r')
plt.hist(Su_dur, bins = 50, label = 'Su_dur', alpha = 0.3, color = 'y')
plt.legend()
plt.show()
订阅用户累计骑行时间远高普通用户,这在用户类别统计中就可推测出。
7.工作日与周末出行情况
# 获取工作日与周末数据
week_da = data_2[data_2['week'].isin([5, 6])]
work_da = data_2[data_2['week'].isin([0, 1, 2, 3, 4])]
# 画了4个图,平日、周末、订阅用户、普通用户的交叉关系
plt.figure(figsize = (20, 10))
# 图1:周末订阅用户、普通用户的骑行时间的分布
plt.subplot(2,2,1)
plt.hist(round(week_da[week_da['user_type'] == 'Subscriber']['duration_sec'] / 3600, 2), bins = 50, label = 'Su',\color = 'r')
plt.hist(round(week_da[week_da['user_type'] == 'Customer']['duration_sec'] / 3600, 2), bins = 50, alpha = 0.5, label = 'Cu',color = 'g')
plt.title('week_day')
plt.legend()# 图2:工作日订阅用户、普通用户的骑行时间的分布
plt.subplot(2,2,2)
plt.hist(round(work_da[work_da['user_type'] == 'Subscriber']['duration_sec'] / 3600, 2), bins = 50, label = 'Su',\color = 'r')
plt.hist(round(work_da[work_da['user_type'] == 'Customer']['duration_sec'] / 3600, 2), bins = 50, alpha = 0.5, label = 'Cu',color = 'g')
plt.title('work_day')
plt.legend()# 图3:订阅用户工作日、周末骑行时间分布
plt.subplot(2,2,3)
plt.hist(round(week_da[week_da['user_type'] == 'Subscriber']['duration_sec'] / 3600, 2), bins = 50, label = 'week',\color = 'r')
plt.hist(round(work_da[work_da['user_type'] == 'Subscriber']['duration_sec'] / 3600, 2), bins = 50, alpha = 0.5, label = 'work',color = 'g')
plt.title('Sub')
plt.legend()# 图4:普通用户工作日、周末骑行时间分布
plt.subplot(2,2,4)
plt.hist(round(week_da[week_da['user_type'] == 'Customer']['duration_sec'] / 3600, 2), bins = 50, label = 'week',\color = 'r')
plt.hist(round(work_da[work_da['user_type'] == 'Customer']['duration_sec'] / 3600, 2), bins = 50, alpha = 0.5, label = 'work',color = 'g')
plt.title('Cu')
plt.legend()plt.show()
- 工作日、周末订阅用户骑行时间占比高,且骑行时间都是在25分钟以内
- 对比工作日,订阅用户在周末骑行时间占比较少,小于50%;对比工作日,普通用户周末骑行时间约占工作日骑行时间的50%
对周末骑行时间较长的普通用户进行进一步分析与用户调研,是否有机会推出周末的低价订阅套餐。
8.站点热度分析
# 最忙的站点分析(出发、结束的前8名)
sss = data_2['start_station_id'].value_counts().sort_values(ascending = False).head(8)
ess = data_2['end_station_id'].value_counts().sort_values(ascending = False).head(8)plt.figure(figsize = (16, 8))
plt.subplot(121)
plt.plot(sss.index, sss.values)
plt.title('start_station')plt.subplot(122)
plt.plot(ess.index, ess.values)
plt.title('end_station')plt.show()
# 起、终点年吞吐前8名
print(round(sss.mean() / 365, 2))
print(round(ess.mean() / 365, 2))
前8名每个站点,平均每天出发93次车,进入106辆车。
这个要结合实际站点情况进行评估,是否有足够的场地,人力进行运营。
# 获取经纬度信息
loc = data_2[['start_station_latitude', 'start_station_longitude', 'end_station_latitude', 'end_station_longitude']]# 查看这些经纬度的区域
plt.figure(figsize = (12, 6))
plt.subplot(1,2,1)
plt.scatter(loc['start_station_latitude'], loc['start_station_longitude'], alpha = 0.3)
plt.title('start')plt.subplot(1,2,2)
plt.scatter(loc['end_station_latitude'], loc['end_station_longitude'], alpha = 0.3)
plt.title('end')plt.show()
观察可知,共享单车主要在这3个区域骑行。
# 分别3个区域的获取经纬度信息
re_a = data_2[data_2['start_station_latitude'] < 37.5]
re_b = data_2[data_2['start_station_longitude'] < -122.45]
re_c = data_2[(data_2['start_station_longitude'] > -122.45) & (data_2['start_station_longitude'] < -122.1)]
# 分别获得3个区域经纬度的平均值
a_la, a_lo = re_a['start_station_latitude'].mean(), re_a['start_station_longitude'].mean()
b_la, b_lo = re_b['start_station_latitude'].mean(), re_b['start_station_longitude'].mean()
c_la, c_lo = re_c['start_station_latitude'].mean(), re_c['start_station_longitude'].mean()
# 绘制3个底图
m_a = folium.Map(location = [a_la, a_lo], zoom_start = 8, control_scale = True)
m_b = folium.Map(location = [a_la, a_lo], zoom_start = 8, control_scale = True)
m_c = folium.Map(location = [a_la, a_lo], zoom_start = 8, control_scale = True)
# 首先分别构造热力图的数据
a_num = re_a.groupby(by = ['start_station_latitude', 'start_station_longitude'], \as_index = False).agg({'start_station_name':'count'})
b_num = re_b.groupby(by = ['start_station_latitude', 'start_station_longitude'], \as_index = False).agg({'start_station_name':'count'})
c_num = re_c.groupby(by = ['start_station_latitude', 'start_station_longitude'], \as_index = False).agg({'start_station_name':'count'})
# 绘制a区域的热力图
HeatMap(a_num).add_to(m_a)
m_a
# 绘制b区域的热力图
HeatMap(b_num).add_to(m_b)
m_b![在这里插入图片描述](https://img-blog.csdnimg.cn/20201101001532714.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ZhbGt5cmphMTEw,size_16,color_FFFFFF,t_70#pic_center)
# 绘制c区域的热力图
HeatMap(c_num).add_to(m_c)
m_c
四、结论
- 异常骑行数据约1万条,车辆无法关锁,用户遗漏关锁,车辆自动开锁。调查异常数据车辆,并评估是否开放提示用户关锁功能与车辆长时间自动关锁的功能。预计在一定成都上能避免用户使用的不便以及减少车辆的运营成本(锁未关,他人随意骑行)。
- 进出站前8的站点,每天进出站平均106、93辆车,需要评估站点是否有足够的空间以及运营人员进行维护。使用次数最多的车辆同样需要进行定期关注维护与保养。
- 十月后用户的骑行时常大幅度减少,是否可以在9月提前推出10月-12月的低价畅骑卡,以此提高冬季的收入。
- 普通用户在周末的骑行时常约占工作日的50%,需要进行深入分析与用户调研,探索普通用户周末的出行需求,评估是否有必要推出周末畅行卡,最大程度增加收入,因为周末车辆闲置无法产生盈利。
美国旧金山共享单车数据分析相关推荐
- sql date类型_共享单车数据分析的SQL数据库设计
SQL,发音为" sequel"(或SQL,如果愿意的话),是数据科学家的重要工具.实际上,它可以说是获取数据工作中最重要的语言.在共享单车数据分析的SQL设计中,我们将从入门者的 ...
- 共享单车数据分析的SQL数据库设计
SQL,发音为" sequel"(或SQL,如果愿意的话),是数据科学家的重要工具.实际上,它可以说是获取数据工作中最重要的语言.在共享单车数据分析的SQL设计中,我们将从入门者的 ...
- 摩拜共享单车数据分析项目报告
文章目录 项目背景 数据探索 数据挖掘 数据分析 时间维度 空间维度 用户维度 项目背景 随着智能手机的普及和手机用户的激增,共享单车作为城市交通系统的一个重要组成部分,以绿色环保.便捷高效.经济环保 ...
- 毕业设计 题目:基于大数据的共享单车数据分析
文章目录 0 前言 1 项目背景 2 项目分析思维导图 3 项目分析具体步骤 3.1 读取数据 3.2 数据分析 3.1.1 数据预处理--每日使用量分析 3.1.2 连续7天的单日使用分析结论 3. ...
- kaggle共享单车数据分析及预测(随机森林)
文章目录 一.数据收集 1.1.项目说明 1.2.数据内容及变量说明 二.数据处理 2.1.导入数据 2.2.缺失值处理 2.3.Label数据(即count)异常值处理 2.4.其他数据异常值处理 ...
- Spark SQL上海摩拜共享单车数据分析
1 生成DataFrame对象 val bikeDF = sqlContext.read.format("csv").option("header", &quo ...
- 美国共享单车数据分析
分析三大美国城市的自行车共享系统相关的数据:芝加哥.纽约和华盛顿特区.写一个脚本,该脚本会接受原始输入并在终端中创建交互式体验,以展现这些统计信息. 目录 数据集说明: 起始时间分析: 骑行时长分析: ...
- 毕业设计 基于大数据的共享单车数据分析与可视化
文章目录 0 前言 1 课题背景 2 数据清洗 3 数据可视化 热力图 整体特征分布 **查看2011-2012间的单车租借情况** 天气对于租借数量的影响 湿度与温度对于租借数量的影响 注册用户与未 ...
- python共享单车数据分析_数据分析_共享单车骑行时间分析-zeropython
数据分析一共分为五个任务: 第一步:明确分析的任务 分析出每个季度的骑行的平均时长和各个季度的对比 第二步:数据处理 先看数据: shell 查看csv 数据前十行 ➜ data cat bikesh ...
- 膜拜共享单车数据分析
数据:2017年5月两周内,北京40余万辆摩拜单车被30余万摩拜用户的使用情况(该开源数据来源于2017年摩拜算法挑战赛).数据包含300余万条出行记录数据,每条的数据包含了订单号(orderid ) ...
最新文章
- 【HeadFirst 设计模式学习笔记】2 观察者模式
- 这届不敢看体检报告的年轻人还能“年轻”多久?
- 驾驶卡丁车 模拟,迷宫(女赛)
- 结对-结对编项目贪吃蛇-设计文档
- AcWing 3208. Z字形扫描
- centos mate桌面_CENTOS7安装各种桌面系统 CENTOS安装桌面图形化GUI GNOME/KDE/Cinnamon/MATE/Xfce...
- 程序员——神圣的职业
- 2008生产实习 日程安排
- H3C ospf与nat转换
- Atitit 浏览器tech原理与概论 目录 1. 浏览器概述	1 1.1. 浏览器野史 UserAgent列传	1 1.2. 浏览器趋势	1 1.3. 浏览器大战	1 1.4. 三次浏览器大战	2
- Zemax操作--9(全局坐标设定及使用方法)
- 证照之星下载证件照制作软件ps及使用教程,附序列号秘钥激活码
- Unity 鼠标点击事件穿透
- 电子签名法学习-(1)电子认证服务机构
- 归一化MinMaxScaler()、标准化StandardScaler()(特征工程之特征预处理)
- Intouch2020与施耐德PLC通讯
- python求组合数c(m、n)编程题_c语言编程问题,计算出从n 个不同元素中取出m 个元素(m≤n)的组合数。编写程序...
- X87 FPU 指令集
- Java包括jvm及API,Java基础(下)(JVM、API)
- 商务汇报PPT制作的七堂课-第三课:结构搭建
热门文章
- Linux文件|菜鸟教程
- 高等数学张宇18讲 第二讲 极限与连续
- ps cc 2014 智能切图
- caj文件添加endnote_endnote怎么导入caj
- word转化为html操作步骤
- 如何将iPhone投屏到Mac电脑上?
- 小程序在wxml里转数字_微信小程序 之wxml保留小数点后两位数的方法及转化为字符串的方法...
- 增长模型—评分卡模型
- error Code:410 Error Message:appid and openid not match 威富通技术支持,兴业银行微信支付接入支持
- python 读取excel表内容:以获取高铁站点经纬度为例子