基于地铁刷卡数据分析与可视化——以杭州市为例(二)

devtools/2024/11/15 2:05:28/

上篇文章提到,由于2019年1月1日正好是元旦,为了消除节假日对数据分析的影响,我们选择了节后的一周来进行详细的客流分析。具体日期选择为2019年1月8日至1月14日。在这段时间内,我们关注的是地铁线路的进站客流情况。数据表中的 'status' 字段表示进出站状态,其中0代表出站,1代表进站。我们的目标是计算这一周内三条地铁线路(A线、B线和C线)的平均进站客流量,以全面了解各线路的客流分布和高峰时段的特点;

完整代码#运行环境Python 3.11

python"># -*- coding: utf-8 -*-import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号# 文件路径列表
file_paths = ['D:\\data\\record_2019-01-08.csv','D:\\data\\record_2019-01-09.csv','D:\\data\\record_2019-01-10.csv','D:\\data\\record_2019-01-11.csv','D:\\data\\record_2019-01-12.csv','D:\\data\\record_2019-01-13.csv','D:\\data\\record_2019-01-14.csv'
]# 存储每个日期的每小时客流量
daily_hourly_counts = []# 读取每个CSV文件并计算每小时客流量
for file_path in file_paths:df = pd.read_csv(file_path)# 确保 'time' 列是 datetime 类型df['time'] = pd.to_datetime(df['time'])# 筛选条件:'lineID' = 'A' 且 'status' = 1filtered_df = df[(df['lineID'] == 'A') & (df['status'] == 1)]# 按 'time' 和 'stationID' 分组,并按小时汇总客流量hourly_station_customer_count = filtered_df.groupby([filtered_df['time'].dt.hour, 'stationID']).size().unstack(fill_value=0)# 将结果存储到列表中daily_hourly_counts.append(hourly_station_customer_count)# 合并所有日期的每小时客流量
combined_hourly_counts = pd.concat(daily_hourly_counts, axis=0)# 计算每个小时各个 stationID 的平均客流量
average_hourly_station_customer_count = combined_hourly_counts.groupby(combined_hourly_counts.index).mean()# 打印结果
print("每个小时各个 'stationID' 的平均客流量:")
print(average_hourly_station_customer_count)# 可视化
plt.figure(figsize=(14, 7))# 为每个 stationID 绘制折线图
for station in average_hourly_station_customer_count.columns:plt.plot(average_hourly_station_customer_count.index, average_hourly_station_customer_count[station], label=f'Station {station}')# 设置图表标题和标签
plt.title('每个小时各个 stationID 的平均客流量')
plt.xlabel('小时')
plt.ylabel('平均客流量')
plt.legend()
plt.grid(True)# 显示图表
plt.show()

我们通过编写Python脚本来计算全天24小时内各个站点的进站客流量变化情况,并进一步对一周内的客流量数据求均值,以全面了解各站点的客流量分布特点;

A线路各个站点在全天的平均进站客流量分布情况

B线路各个站点在全天的平均进站客流量分布情况

C线路各个站点在全天的平均进站客流量分布情况

我们把数据的研究尺度进一步缩小,同样的,我们通过python脚本来计算一下,全天24小时的各个站点进站客流的早晚高峰峰值区间分布情况,并对一周的客流量求均值,我们来看各线路早晚高峰的15分钟峰值客流分布情况;

完整代码#运行环境Python 3.11

python"># -*- coding: utf-8 -*-import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号def read_and_process_file(file_path):try:df = pd.read_csv(file_path)df['time'] = pd.to_datetime(df['time'])filtered_df = df[(df['lineID'] == 'A') & (df['status'] == 1)]# 按15分钟分组fifteen_minute_station_customer_count = filtered_df.groupby([pd.Grouper(key='time', freq='15min'), 'stationID']).size().unstack(fill_value=0)return fifteen_minute_station_customer_countexcept Exception as e:print(f"Error processing file {file_path}: {e}")return None# 文件路径列表
file_paths = ['D:\\data\\record_2019-01-08.csv','D:\\data\\record_2019-01-09.csv','D:\\data\\record_2019-01-10.csv','D:\\data\\record_2019-01-11.csv','D:\\data\\record_2019-01-12.csv','D:\\data\\record_2019-01-13.csv','D:\\data\\record_2019-01-14.csv'
]# 存储每个日期的每15分钟客流量
daily_fifteen_minute_counts = []# 读取每个CSV文件并计算每15分钟客流量
for file_path in file_paths:fifteen_minute_station_customer_count = read_and_process_file(file_path)if fifteen_minute_station_customer_count is not None:daily_fifteen_minute_counts.append(fifteen_minute_station_customer_count)# 合并所有日期的每15分钟客流量
combined_fifteen_minute_counts = pd.concat(daily_fifteen_minute_counts, axis=0)# 计算每15分钟各个 stationID 的平均客流量
average_fifteen_minute_station_customer_count = combined_fifteen_minute_counts.groupby(combined_fifteen_minute_counts.index.time).mean()# 将索引转换为 DatetimeIndex
average_fifteen_minute_station_customer_count.index = pd.to_datetime(average_fifteen_minute_station_customer_count.index, format='%H:%M:%S')# 打印结果
print("每15分钟各个 'stationID' 的平均客流量:")
print(average_fifteen_minute_station_customer_count)# 确定早高峰和晚高峰15分钟区间
peak_intervals = {}
for station in average_fifteen_minute_station_customer_count.columns:# 早高峰时间段morning_peak = average_fifteen_minute_station_customer_count.between_time('06:00', '10:00')[station].idxmax()# 晚高峰时间段evening_peak = average_fifteen_minute_station_customer_count.between_time('16:00', '20:00')[station].idxmax()formatted_morning_peak = f"{morning_peak.strftime('%H:%M')}-{(morning_peak + pd.Timedelta(minutes=15)).strftime('%H:%M')}"formatted_evening_peak = f"{evening_peak.strftime('%H:%M')}-{(evening_peak + pd.Timedelta(minutes=15)).strftime('%H:%M')}"peak_intervals[station] = {'morning': formatted_morning_peak,'evening': formatted_evening_peak}# 输出每个站点的早高峰和晚高峰15分钟区间
print("\n各站点早高峰和晚高峰进站客流的15分钟区间:")
for station, intervals in peak_intervals.items():print(f"Station {station}: 早高峰 {intervals['morning']}, 晚高峰 {intervals['evening']}")# 可视化
fig, ax = plt.subplots(figsize=(14, 8))# 为每个 stationID 绘制24小时刻度图
cmap = plt.get_cmap('tab10')  # 获取颜色映射
colors = [cmap(i % cmap.N) for i in range(len(peak_intervals))]for i, (station, intervals) in enumerate(peak_intervals.items()):# 早高峰start_time, end_time = intervals['morning'].split('-')start_hour = int(start_time[:2]) + int(start_time[3:]) / 60end_hour = int(end_time[:2]) + int(end_time[3:]) / 60ax.axvspan(start_hour, end_hour, alpha=0.3, color=colors[i],label=f'Station {station} 早高峰 {intervals["morning"]}')# 晚高峰start_time, end_time = intervals['evening'].split('-')start_hour = int(start_time[:2]) + int(start_time[3:]) / 60end_hour = int(end_time[:2]) + int(end_time[3:]) / 60ax.axvspan(start_hour, end_hour, alpha=0.3, color=colors[i],label=f'Station {station} 晚高峰 {intervals["evening"]}')# 设置图表标题和标签
ax.set_title('各站点早高峰和晚高峰进站客流的15分钟区间')
ax.set_xlabel('时间 (小时)')
ax.set_ylabel('客流量')
ax.set_xlim(0, 24)
ax.set_xticks(range(25))
ax.set_xticklabels([f'{i}:00' if i % 2 == 0 else '' for i in range(25)])# 调整图例的位置和大小
ax.legend(loc='upper left', bbox_to_anchor=(1.05, 1), borderaxespad=0., fontsize='small')# 手动调整子图之间的间距
plt.subplots_adjust(left=0.1, right=0.8, top=0.9, bottom=0.1)# 显示图表
plt.show()

整体来说,这些线路的早高峰时间段: 大多数站点的早高峰集中在08:00-08:30之间,特别是08:00-08:15和08:15-08:30两个时间段。 个别站点的早高峰时间较晚,如Station 76(09:45-10:00)和Station 77(09:30-09:45);我们可以看到,晚高峰的分布时刻带更宽,根据站点的分布情况和地理位置等情况,个站点晚高峰到来的时刻更早或晚,大多数站点的晚高峰集中在17:15-18:00之间,特别是17:15-17:30和17:30-17:45两个时间段;

A线路各个站点在全天的进站客流量中,早晚高峰15分钟的最大客流时刻分布情况

B线路各个站点在全天的进站客流量中,早晚高峰15分钟的最大客流时刻分布情况

C线路各个站点在全天的进站客流量中,早晚高峰15分钟的最大客流时刻分布情况

我们使用Python脚本再来探究一下地铁各线路的进站客流数据进行分析,找出各线路进站客流前10名的站点客流分布情况和特征;

完整代码#运行环境Python 3.11

python"># -*- coding: utf-8 -*-import pandas as pddef read_and_process_file(file_path):try:df = pd.read_csv(file_path)df['time'] = pd.to_datetime(df['time'])return dfexcept Exception as e:print(f"Error processing file {file_path}: {e}")return None# 文件路径列表
file_paths = ['D:\\data\\record_2019-01-08.csv','D:\\data\\record_2019-01-09.csv','D:\\data\\record_2019-01-10.csv','D:\\data\\record_2019-01-11.csv','D:\\data\\record_2019-01-12.csv','D:\\data\\record_2019-01-13.csv','D:\\data\\record_2019-01-14.csv'
]# 读取并处理所有文件
dfs = [read_and_process_file(file_path) for file_path in file_paths]
df = pd.concat(dfs, ignore_index=True)# 过滤 A 线的数据
a_line_data = df[df['lineID'] == 'A']# 提取进站数据
inbound_data = a_line_data[a_line_data['status'] == 1]# 计算每天的平均进站客流
daily_inbound_flow = inbound_data.groupby([inbound_data['time'].dt.date, 'stationID'])['userID'].count().reset_index()
daily_inbound_flow.columns = ['date', 'stationID', 'inbound_count']# 计算每个站点的平均进站客流
average_inbound_flow = daily_inbound_flow.groupby('stationID')['inbound_count'].mean().reset_index()
average_inbound_flow.columns = ['stationID', 'average_inbound_count']# 按平均进站客流排序并取前10名
top_10_inbound_stations = average_inbound_flow.sort_values(by='average_inbound_count', ascending=False).head(10)# 输出前10名站点的平均进站客流到 CSV 文件
output_file_path = 'D:\\data\\top_10_inbound_stations.csv'
top_10_inbound_stations.to_csv(output_file_path, index=False)
print(f"Top 10 inbound stations data saved to {output_file_path}")

我们可以看到A线路每天平均进站客流前10名站点客流呈阶梯式递减,B线路每天平均进站客流前10名站点中编码15的站点客流占大头,其他客流呈较为相似状态,差别不大,C线路每天平均进站客流前10名站点中,客流客流较为均衡,线路整体各站点进站客流较为平稳;

A线路每天平均进站客流前10名站点

B线路每天平均进站客流前10名站点

C线路每天平均进站客流前10名站点

文章仅用于分享个人学习成果与个人存档之用,分享知识,如有侵权,请联系作者进行删除。所有信息均基于作者的个人理解和经验,不代表任何官方立场或权威解读。


http://www.ppmy.cn/devtools/133024.html

相关文章

理解虚拟 DOM:Vue 的灵魂之处

理解虚拟 DOM:Vue 的灵魂之处 在现代前端开发中,性能是一个至关重要的考虑因素。Vue.js 作为一款流行的前端框架,其中一个让人称道的特性就是它的“虚拟 DOM”。那么,虚拟 DOM 是什么?它是如何工作的?本文…

Java中的线程安全问题(如果想知道Java中有关线程安全问题的基本知识,那么只看这一篇就足够了!)

前言:多线程编程已经广泛开始使用,其可以充分利用系统资源来提升效率,但是线程安全问题也随之出现,它直接影响了程序的正确性和稳定性,需要对其进行深入的理解与解决。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解…

树莓派AI视觉小车--5.机器人小车超声波避障

通过超声波模块与小车结合,实现小车超声波避障。确保小车接线已安装,且安装正确。 通过超声波来获取小车与障碍物的距离。当检测到小车与障碍物的距离小于我们的设置的距离时,小车左旋避开障碍物。 运行代码如下所示: from LOBO…

漏洞分析 | Spring Framework路径遍历漏洞(CVE-2024-38816)

漏洞概述 VMware Spring Framework是美国威睿(VMware)公司的一套开源的Java、JavaEE应用程序框架。该框架可帮助开发人员构建高质量的应用。 近期,网宿安全演武实验室监测到Spring Framework在特定条件下,存在目录遍历漏洞&…

A20红色革命文物征集管理系统

🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…

HiveMetastore 的架构简析

HiveMetastore 的架构简析 Hive Metastore 是 Hive 元数据管理的服务。可以把元数据存储在数据库中。对外通过 api 访问。 hive_metastore.thrift 对外提供的 Thrift 接口定义在文件 standalone-metastore/src/main/thrift/hive_metastore.thrift 中。 内容包括用到的结构体…

WebFlux/r2dbc/mysql增删改查Demo

WebFlux/r2dbc/mysql增删改查Demo 环境和版本依赖配置模仿MybtisPlus的BaseMapper和Service验证 环境和版本 jdk1.8springboot 2.7.6idea 依赖 pom.xml部分内容&#xff1a; <properties><java.version>1.8</java.version><project.build.sourceEncod…

ORACLE批量插入更新如何拆分大事务?

拆分大事务 一、批量插入更新二、拆分事务之前文章MYSQL批量插入更新如何拆分大事务?说明了Mysql如何拆分,本篇文章探讨Oracle或OceanBase批量插入更新拆分大事务的问题 一、批量插入更新 oracle批量插入更新可使用merge语法eg: merge test ausing test_tmp bon (a.id = b.id…