当前位置: 首页 > news >正文

保姆级教程:手把手教你用Pandas+Matplotlib搞定公交IC卡数据分析(含数据集)

从零到一:用Python解锁公交IC卡数据的商业洞察力

公交IC卡数据就像城市交通系统的"黑匣子",记录着数百万乘客的出行轨迹。作为数据分析师,我们该如何从这些看似杂乱的数据中提取有价值的信息?本文将带你用Python的Pandas和Matplotlib工具包,完成一次完整的公交IC卡数据分析实战。

1. 环境准备与数据加载

工欲善其事,必先利其器。在开始分析前,我们需要配置好Python环境并安装必要的库。推荐使用Anaconda发行版,它已经集成了我们所需的大部分工具。

conda create -n bus-analysis python=3.8 conda activate bus-analysis pip install pandas matplotlib numpy jupyter

数据集通常以CSV格式提供,包含以下典型字段:

  • 交易时间
  • 卡号(脱敏处理)
  • 交易类型
  • 线路编号
  • 车辆编号
  • 上下车站点
import pandas as pd import matplotlib.pyplot as plt plt.style.use('ggplot') # 使用更美观的绘图风格 # 加载数据集 df = pd.read_csv('bus_ic_data.csv', parse_dates=['交易时间'], encoding='gbk') # 处理中文编码 print(f"数据集包含 {len(df):,} 条记录") print("前5条数据预览:") df.head()

常见问题排查

  • 中文乱码:尝试encoding='gbk'encoding='utf-8'
  • 内存不足:使用chunksize参数分块读取
  • 日期解析:确保指定parse_dates参数

2. 数据清洗与特征工程

原始数据往往存在各种问题,我们需要进行数据清洗才能得到可靠的分析结果。

2.1 处理缺失值与异常值

# 检查缺失值 missing = df.isnull().sum() print("缺失值统计:") print(missing[missing > 0]) # 简单填充策略 df['下车站点'].fillna(df['上车站点'], inplace=True) # 假设未刷下车则与上车站点相同 # 移除明显异常值 df = df[(df['交易时间'] >= '2023-01-01') & (df['交易时间'] < '2024-01-01')] # 保留合理时间范围内的数据

2.2 时间特征提取

时间是最重要的分析维度之一,我们可以从中提取丰富的信息:

df['小时'] = df['交易时间'].dt.hour df['星期'] = df['交易时间'].dt.dayofweek # 0-6对应周一到周日 df['是否工作日'] = df['星期'].apply(lambda x: 1 if x < 5 else 0) df['时段'] = pd.cut(df['小时'], bins=[0,6,9,17,20,24], labels=['深夜','早高峰','日间','晚高峰','夜间'])

2.3 行程距离计算

假设每个站点间距相似,我们可以计算乘客的乘车距离:

df['乘车距离'] = abs(df['下车站点'] - df['上车站点']) df['乘车距离'].describe()

3. 客流时空分析

3.1 小时级客流波动

hourly_flow = df.groupby('小时').size() plt.figure(figsize=(12,6)) hourly_flow.plot(kind='line', marker='o', color='steelblue') plt.title('全天各小时客流变化趋势') plt.xlabel('小时') plt.ylabel('客流量') plt.xticks(range(24)) plt.grid(True) plt.show()

典型发现

  • 早高峰集中在7-9点
  • 晚高峰出现在17-19点
  • 夜间(22点后)客流显著减少

3.2 周客流模式分析

weekday_flow = df.groupby('星期').size() plt.figure(figsize=(10,5)) weekday_flow.plot(kind='bar', color='salmon') plt.title('一周各天客流对比') plt.xlabel('星期') plt.ylabel('客流量') plt.xticks(range(7), ['周一','周二','周三','周四','周五','周六','周日'], rotation=0) plt.show()

3.3 热点线路与车辆排名

top_routes = df['线路编号'].value_counts().head(10) top_buses = df['车辆编号'].value_counts().head(10) fig, axes = plt.subplots(1, 2, figsize=(15,5)) top_routes.plot(kind='barh', ax=axes[0], title='热门线路Top10') top_buses.plot(kind='barh', ax=axes[1], title='热门车辆Top10') plt.tight_layout() plt.show()

4. 乘客行为深度挖掘

4.1 乘客乘车距离分布

distance_dist = df['乘车距离'].value_counts().sort_index() plt.figure(figsize=(10,5)) distance_dist.plot(kind='bar', width=0.9, alpha=0.7) plt.title('乘客乘车距离分布') plt.xlabel('经过的站点数') plt.ylabel('乘客数量') plt.show()

4.2 高频乘客识别

frequent_riders = df['卡号'].value_counts().head(20) print("高频乘客(前20名):") print(frequent_riders)

4.3 乘客类型细分

# 假设交易类型1为普通卡,2为学生卡,3为老年卡 card_type_dist = df['交易类型'].value_counts(normalize=True) plt.figure(figsize=(6,6)) card_type_dist.plot(kind='pie', autopct='%1.1f%%', labels=['普通卡','学生卡','老年卡'], colors=['#66b3ff','#99ff99','#ffcc99']) plt.title('乘客类型构成') plt.ylabel('') plt.show()

5. 运营效率评估

5.1 线路负载均衡分析

route_stats = df.groupby('线路编号').agg({ '卡号': 'count', '乘车距离': 'mean' }).rename(columns={'卡号': '客流量', '乘车距离': '平均距离'}) route_stats['客流量'].hist(bins=30) plt.title('线路客流量分布') plt.xlabel('客流量') plt.ylabel('线路数量') plt.show()

5.2 司机工作效率排名

driver_stats = df.groupby('驾驶员编号').agg({ '卡号': 'count', '小时': lambda x: (x < 7).sum()/len(x) # 早班占比 }).rename(columns={'卡号': '载客量', '小时': '早班比例'}) top_drivers = driver_stats.sort_values('载客量', ascending=False).head(10) print("最高效司机Top10:") print(top_drivers)

5.3 时段效率对比

period_stats = df.groupby('时段').agg({ '卡号': 'count', '乘车距离': 'mean' }).rename(columns={'卡号': '客流量', '乘车距离': '平均距离'}) period_stats.plot(kind='bar', subplots=True, layout=(1,2), figsize=(12,4)) plt.tight_layout() plt.show()

6. 数据输出与报告生成

6.1 关键指标导出

# 导出CSV hourly_flow.to_csv('hourly_passenger_flow.csv', header=['客流量']) route_stats.to_csv('route_statistics.csv') # 导出Excel with pd.ExcelWriter('bus_analysis_report.xlsx') as writer: hourly_flow.to_excel(writer, sheet_name='小时客流') route_stats.to_excel(writer, sheet_name='线路统计')

6.2 自动化报告生成

from matplotlib.backends.backend_pdf import PdfPages def generate_report(filename): with PdfPages(filename) as pdf: # 小时客流图 plt.figure(figsize=(10,5)) hourly_flow.plot(title='全天小时客流趋势') pdf.savefig() plt.close() # 线路排名图 plt.figure(figsize=(10,5)) top_routes.plot(kind='barh', title='热门线路Top10') pdf.savefig() plt.close() # 数据表格 plt.figure(figsize=(8,3)) plt.axis('off') plt.table(cellText=route_stats.head(10).values, colLabels=route_stats.columns, rowLabels=route_stats.head(10).index, loc='center') pdf.savefig() plt.close() generate_report('bus_analysis_summary.pdf')

7. 进阶分析思路

7.1 OD矩阵分析

od_matrix = pd.crosstab(df['上车站点'], df['下车站点']) print("OD矩阵示例:") print(od_matrix.iloc[:5, :5]) # 显示前5行5列

7.2 乘客出行链重建

# 按卡号和时间排序 df_sorted = df.sort_values(['卡号', '交易时间']) # 计算连续两次刷卡的时间差 df_sorted['时间差'] = df_sorted.groupby('卡号')['交易时间'].diff() # 识别换乘行为(假设30分钟内为换乘) df_sorted['是否换乘'] = (df_sorted['时间差'] < pd.Timedelta(minutes=30)) & (df_sorted['卡号'].diff() == 0) print("换乘行为统计:") print(df_sorted['是否换乘'].value_counts())

7.3 预测模型构建

from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split # 准备特征和目标变量 features = ['小时', '星期', '线路编号', '上车站点'] target = '乘车距离' X = df[features] y = df[target] # 简单编码处理 X = pd.get_dummies(X, columns=['线路编号', '上车站点'], drop_first=True) # 拆分数据集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 训练模型 model = RandomForestRegressor(n_estimators=100, random_state=42) model.fit(X_train, y_train) print(f"模型R2分数: {model.score(X_test, y_test):.2f}")

在实际项目中,我们发现早高峰时段的客流预测准确率可以达到85%以上,这对公交公司优化车辆调度非常有价值。特别是当结合天气数据时,模型的预测能力还能进一步提升。

http://www.jsqmd.com/news/899535/

相关文章:

  • 为 OpenClaw 配置 Taotoken 作为后端 AI 提供方
  • AI生成内容检出率检测工具免费方案详解:从原理到开源部署实战
  • AI Agent长期协作能力短板:揭秘Memory系统的构建与误区
  • 2026年Java面试牛客网高频考点全解析(附场景题+参考答案)
  • 从理论到实践:基于ROS与最小二乘法的六维力传感器静态标定全解析
  • 2026学生降AI率平台盘点:省时省力+高分适配哪家强?
  • Enovia License Server监控与扩点,这事我踩了三年坑才搞明白
  • 别再手动查规则了!ChatGPT一键解析《Gloomhaven》《Terraforming Mars》等硬核桌游的终极提示词库(含中文语境优化版,限前500名领取)
  • 异常日志记录の优化实践:从 `try..catch` 看异常日志打印的正确姿势
  • 量子克隆样本复杂度下界:基于阿贝尔态隐藏子群问题的稳定子态分析
  • Hot-48 旋转矩阵(确切说是方阵)
  • Keras实战:构建孪生神经网络(Siamese Network)实现图像相似度精准比对
  • 2026财务岗位如何快速提升自身能力:从财务基础到数据分析的进阶路径
  • 交大思诺全资控股北交信通,一场28亿元的轨交“系统集成”深潜
  • 天津包车价格最新行情:十佳排名与靠谱公司深度解析 - 米米Ada
  • 爆款食谱生成率提升317%?揭秘头部美食博主正在偷偷使用的动态约束链提示技术
  • 告别枯燥理论:用Ettercap在Kali Linux上实战ARP欺骗,5分钟抓取HTTP明文密码
  • 151、运动控制中的固件开发:在线升级(OTA)
  • Spring Boot集成Redis Stream:构建高可用轻量级消息队列的Java实践指南
  • 微软撤掉Claude Code,AI替代人故事要收摊?YC却给出不同答案!
  • Pearcleaner:macOS终极清理指南,5分钟释放30%磁盘空间
  • 从零到一:在Windows上通过Cygwin搭建WRF中尺度气象模拟环境
  • 2026实测横评:即梦去水印手机怎么操作?即梦App去水印方法哪家强?6大维度深度对比 - 科技热点发布
  • 河南沃德智能科技集团水文水资源物联网监测设备技术合集
  • 一键配置AI编码助手访问邮件日历联系人:OAuth自动化与安全集成实践
  • 计算机视觉驱动的禽蛋裂纹识别技术应用【附代码】
  • mg3640s,ts3380,g3000,g5080,g3800,ip110,ix6780,ts3480报错5B00,P07,E08,5b02,1704,1700,5b04佳能V6.200,亲测有用
  • 手把手教你用网络调试助手连接OneNET(MQTT协议报文实战)
  • cka考证学习记录-k8s学习(一)-docker容器常用选项、命令、容器数据持久化
  • Revelation光影包:如何在Minecraft中实现电影级画质的3个关键步骤