用Python分析20万条公交IC卡数据,手把手教你从数据清洗到可视化(附完整代码)

发布时间:2026/5/28 17:35:44

用Python分析20万条公交IC卡数据,手把手教你从数据清洗到可视化(附完整代码) 从公交IC卡数据挖掘城市脉搏Python数据分析实战全流程解析清晨6:30的早班车总能看到睡眼惺忪的上班族而晚归的夜班车则载着加班的都市人——这些隐藏在公交IC卡数据中的生活轨迹正是城市运行的微观镜像。本文将带您用Python解剖20万条真实公交数据从原始数据到商业洞察完整重现数据分析师的工作流。1. 环境准备与数据初探工欲善其事必先利其器。我们选择Python 3.8作为分析环境主要依赖以下工具库# 核心工具库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 辅助工具 from datetime import datetime from collections import Counter import os典型数据集结构示例字段名类型描述示例值card_idstring卡号A1B2C3trans_timedatetime交易时间2023-05-15 07:30:22line_noint线路编号1105vehicle_nostring车辆编号BJ-AC-2021driver_idstring司机编号DR-028提示实际分析前建议先使用df.info()快速了解数据概况包括各字段非空值数量、内存占用等信息。初次接触原始数据时常见的数据质量问题包括时间格式不统一如混合使用/和-分隔符站点编码存在异常值如负数或超大数值交易记录中存在测试数据如连续相同卡号的密集刷卡2. 数据清洗实战技巧真实世界的数据从来不会乖乖听话。以下是处理公交IC卡数据的典型清洗流程2.1 时间维度处理# 标准化时间格式 df[trans_time] pd.to_datetime(df[trans_time], format%Y/%m/%d %H:%M:%S, errorscoerce) # 提取时间特征 df[hour] df[trans_time].dt.hour df[day_of_week] df[trans_time].dt.dayofweek # 周一为0 df[is_weekend] df[day_of_week] 5时间数据常见问题处理方案异常时间戳过滤掉未来日期或过于久远的历史记录valid_mask (df[trans_time] 2020-01-01) (df[trans_time] 2023-12-31) df df[valid_mask].copy()时间区间不连续通过重采样补充缺失时段hourly_counts df.set_index(trans_time).resample(H).size()2.2 空间维度清洗公交站点数据常出现的两类问题需要特别处理站点跳变异常当相邻记录时间间隔过短但站点跨度极大时可能是数据采集错误# 计算相邻记录时间差秒 df[time_diff] df.groupby(card_id)[trans_time].diff().dt.total_seconds() # 标记异常行程5分钟内移动超过20站 df[abnormal_trip] (abs(df[上车站点] - df[下车站点]) 20) (df[time_diff] 300)站点地理映射将数字编码转换为实际站名需外部地理信息表station_map pd.read_csv(station_mapping.csv) df df.merge(station_map, left_on上车站点, right_onstation_code)3. 核心分析维度拆解公交数据如同城市血管的造影剂可以从多个角度解读城市活力。3.1 时间规律分析典型时间分布模式# 绘制24小时客流热力图 plt.figure(figsize(12, 6)) hourly_pivot df.pivot_table(indexhour, columnsday_of_week, valuescard_id, aggfunccount) sns.heatmap(hourly_pivot, cmapYlOrRd) plt.title(Weekly Hourly Passenger Flow)通过时间分析我们通常能发现早高峰7:00-9:00与晚高峰17:00-19:00的客流差异周末的平峰期特征如购物出行集中在10:00-16:00夜班线路的特殊模式22:00-6:00的离散分布3.2 空间分布洞察线路负载分析是优化公交网络的重要依据# 计算各线路客运强度 line_stats df.groupby(line_no).agg({ card_id: count, 上车站点: pd.Series.nunique }).rename(columns{card_id: passenger_count, 上车站点: station_count}) line_stats[load_factor] line_stats[passenger_count] / line_stats[station_count] top10_lines line_stats.nlargest(10, load_factor)线路优化建议生成逻辑高负载线路增加班次或改用大容量车型低效线路站点过密500米的考虑合并站点特殊线路连接产业园区的通勤专线可调整发车时间4. 高级分析技巧超越基础统计挖掘数据深层价值。4.1 乘客出行链还原通过卡号关联构建完整出行轨迹# 按卡号和时间排序 df_sorted df.sort_values([card_id, trans_time]) # 标记换乘行为30分钟内不同线路连续刷卡 df_sorted[next_line] df_sorted.groupby(card_id)[line_no].shift(-1) df_sorted[next_time] df_sorted.groupby(card_id)[trans_time].shift(-1) df_sorted[transfer] (df_sorted[next_line] ! df_sorted[line_no]) \ ((df_sorted[next_time] - df_sorted[trans_time]).dt.total_seconds() 1800)4.2 司机行为分析模型评估司机驾驶习惯与运营效率# 计算每位司机的平均行程时间 driver_stats df.groupby(driver_id).agg({ trans_time: lambda x: (x.max() - x.min()).total_seconds() / 3600, card_id: count }).rename(columns{trans_time: working_hours, card_id: trip_count}) driver_stats[efficiency] driver_stats[trip_count] / driver_stats[working_hours]司机KPI指标体系指标计算公式优化方向客运效率载客量/工作时间减少空驶时间准点率实际到站时间偏差优化行车节奏平稳度急加减速次数改善驾驶习惯5. 成果可视化呈现让数据自己讲故事是分析的最后一步也是最重要的一步。5.1 动态客流仪表盘# 使用Plotly创建交互图表 import plotly.express as px fig px.density_heatmap(df, xhour, yday_of_week, zcard_id, histfunccount, nbinsx24, nbinsy7, color_continuous_scaleViridis) fig.update_layout(titlePassenger Flow by Hour and Weekday) fig.show()5.2 线路网络关系图# 构建站点连接矩阵 station_pairs df.groupby([上车站点, 下车站点]).size().reset_index(namecounts) # 使用NetworkX绘制拓扑图 import networkx as nx G nx.from_pandas_edgelist(station_pairs, 上车站点, 下车站点, edge_attrcounts) nx.draw_kamada_kawai(G, node_size50, width0.5)在完成所有分析后建议将关键结果保存为结构化报告with pd.ExcelWriter(analysis_report.xlsx) as writer: line_stats.to_excel(writer, sheet_nameLine Statistics) driver_stats.to_excel(writer, sheet_nameDriver Performance) pd.DataFrame(top_routes).to_excel(writer, sheet_nameRoute Recommendations)从清洗数据时的各种异常处理到发现晚高峰特定线路的异常拥挤模式再到最终为公交调度提供数据支持这个20万条记录的数据集教会我们真正的数据分析永远在解决实际问题的路上。当看到自己优化的线路方案真的缓解了早高峰拥挤时那种成就感远比任何技术指标都来得真实。

相关新闻