共享单车时空分布分析:基于 Pandas 与 GeoPandas 的 4 步数据处理流程
共享单车时空数据分析实战从原始数据到可视化洞察的完整流程在当今城市交通体系中共享单车已成为解决最后一公里问题的重要选择。随着GPS定位技术的普及这些单车产生了海量的时空数据为城市规划和交通管理提供了宝贵资源。本文将带你完整实现一个共享单车时空分布分析项目从原始数据处理到最终可视化呈现。1. 数据准备与清洗任何数据分析项目的第一步都是确保数据质量。我们以某城市共享单车的骑行记录数据为例原始数据集通常包含以下字段start_time: 骑行开始时间end_time: 骑行结束时间start_location: 起点经纬度end_location: 终点经纬度user_id: 用户唯一标识track: 骑行轨迹点序列首先使用Pandas加载数据并检查基本信息import pandas as pd # 读取数据 data pd.read_csv(mobike_data.csv) # 查看数据概览 print(f数据集包含 {len(data)} 条记录) print(前5条记录) print(data.head()) # 检查缺失值 print(\n各字段缺失值统计) print(data.isnull().sum())常见的数据清洗操作包括时间格式标准化将字符串时间转换为datetime对象异常值过滤剔除骑行时间过长或过短的记录坐标校验确保经纬度在合理范围内轨迹解析将轨迹字符串转换为坐标序列# 时间格式转换 data[start_time] pd.to_datetime(data[start_time]) data[end_time] pd.to_datetime(data[end_time]) # 计算骑行时长分钟 data[duration] (data[end_time] - data[start_time]).dt.total_seconds()/60 # 过滤异常值保留骑行时间在1分钟到4小时之间的记录 data data[(data[duration] 1) (data[duration] 240)] # 解析轨迹数据 def parse_track(track_str): points track_str.split(#) return [tuple(map(float, p.split(,))) for p in points] data[track_points] data[track].apply(parse_track)2. 时空特征工程高质量的特征是分析的基础。对于共享单车数据我们可以提取以下几类特征2.1 时间维度特征小时级特征骑行开始小时、工作日/周末时段划分早高峰、晚高峰等时间片统计按15/30/60分钟分组# 提取时间特征 data[start_hour] data[start_time].dt.hour data[weekday] data[start_time].dt.weekday data[is_weekend] data[weekday] 5 # 定义时间段 def get_time_period(hour): if 6 hour 9: return 早高峰 elif 17 hour 20: return 晚高峰 elif 9 hour 17: return 日间 else: return 夜间 data[time_period] data[start_hour].apply(get_time_period)2.2 空间维度特征骑行距离使用Haversine公式计算区域划分将城市划分为若干区域如1km×1km网格OD矩阵出发地-目的地流量矩阵from math import radians, sin, cos, sqrt, asin def haversine(lon1, lat1, lon2, lat2): # 计算两点间距离(km) lon1, lat1, lon2, lat2 map(radians, [lon1, lat1, lon2, lat2]) dlon lon2 - lon1 dlat lat2 - lat1 a sin(dlat/2)**2 cos(lat1) * cos(lat2) * sin(dlon/2)**2 return 2 * 6371 * asin(sqrt(a)) # 计算骑行距离 data[distance] data.apply( lambda x: haversine(x[start_lng], x[start_lat], x[end_lng], x[end_lat]), axis1) # 定义区域划分函数示例将城市划分为1km×1km网格 def get_grid_id(lng, lat, lng_step0.01, lat_step0.01): return f{(lng//lng_step)*lng_step}-{(lat//lat_step)*lat_step} data[start_grid] data.apply( lambda x: get_grid_id(x[start_lng], x[start_lat]), axis1) data[end_grid] data.apply( lambda x: get_grid_id(x[end_lng], x[end_lat]), axis1)3. 时空分布分析3.1 时间分布模式分析单车使用的时间规律可以帮助优化调度策略。我们可以从多个时间维度进行分析import matplotlib.pyplot as plt # 按小时统计骑行量 hourly_counts data.groupby(start_hour).size() plt.figure(figsize(12, 6)) hourly_counts.plot(kindbar, colorskyblue) plt.title(每小时骑行量分布) plt.xlabel(小时) plt.ylabel(骑行次数) plt.grid(axisy, linestyle--) plt.show()典型的时间分布特征可能包括工作日模式早晚高峰明显周末模式日间使用量平稳季节变化夏季使用量高于冬季3.2 空间分布模式空间分析的核心是构建OD矩阵Origin-Destination Matrix它描述了不同区域间的单车流动情况。# 构建OD矩阵 od_matrix data.groupby([start_grid, end_grid]).size().unstack(fill_value0) # 热门出发地和目的地 top_origins data[start_grid].value_counts().head(10) top_dests data[end_grid].value_counts().head(10) print(热门出发地区域) print(top_origins) print(\n热门到达地区域) print(top_dests)空间分布分析的关键指标指标计算公式意义区域活跃度出发或到达该区域的骑行次数识别热点区域区域平衡指数(到达量-出发量)/总流量判断车辆过剩或不足区域关联度两区域间双向流量之和发现强关联区域对4. 地理空间可视化GeoPandas是Python中处理地理空间数据的利器结合matplotlib或folium可以实现丰富的可视化效果。4.1 基础地图绘制首先需要准备城市的地理边界数据如GeoJSON格式然后绘制骑行热力图import geopandas as gpd from shapely.geometry import Point # 创建GeoDataFrame geometry [Point(xy) for xy in zip(data[start_lng], data[start_lat])] gdf gpd.GeoDataFrame(data, geometrygeometry, crsEPSG:4326) # 读取城市边界 city gpd.read_file(city_boundary.geojson) # 绘制热力图 fig, ax plt.subplots(figsize(12, 10)) city.plot(axax, colorlightgray, edgecolorblack) gdf.plot(axax, markersize2, colorred, alpha0.5) plt.title(共享单车起点分布热力图) plt.axis(off) plt.show()4.2 交互式地图使用folium可以创建交互式地图更适合展示时空数据import folium from folium.plugins import HeatMap # 创建基础地图 m folium.Map(location[city.centroid.y.mean(), city.centroid.x.mean()], zoom_start12) # 添加热力图层 heat_data [[row[start_lat], row[start_lng]] for _, row in data.iterrows()] HeatMap(heat_data, radius10).add_to(m) # 添加区域边界 folium.GeoJson(city).add_to(m) # 保存为HTML文件 m.save(bike_heatmap.html)4.3 时空立方体可视化对于同时包含时间和空间维度的数据可以使用时序动画来展示变化import matplotlib.animation as animation from IPython.display import HTML # 按小时分组 hourly_groups data.groupby(start_hour) # 创建图形 fig, ax plt.subplots(figsize(12, 10)) city.plot(axax, colorlightgray, edgecolorblack) def update(hour): ax.clear() city.plot(axax, colorlightgray, edgecolorblack) group hourly_groups.get_group(hour) geometry [Point(xy) for xy in zip(group[start_lng], group[start_lat])] gdf gpd.GeoDataFrame(group, geometrygeometry, crsEPSG:4326) gdf.plot(axax, markersize3, colorblue, alpha0.7) ax.set_title(f小时 {hour}:00 单车分布) ax.axis(off) # 创建动画 ani animation.FuncAnimation(fig, update, framesrange(24), interval500) HTML(ani.to_jshtml())5. 高级分析与应用5.1 供需不平衡分析通过比较单车供给和骑行需求可以识别供需失衡的区域# 计算每个区域的净流量到达-出发 grid_net_flow data.groupby(end_grid).size() - data.groupby(start_grid).size() # 识别严重不平衡区域 supply_shortage grid_net_flow[grid_net_flow 50] # 净流入大于50次的区域 excess_supply grid_net_flow[grid_net_flow -50] # 净流出大于50次的区域 print(车辆短缺区域) print(supply_shortage.sort_values(ascendingFalse).head()) print(\n车辆过剩区域) print(excess_supply.sort_values().head())5.2 调度优化建议基于上述分析可以提出针对性的调度建议高峰时段调度在早高峰前将车辆从住宅区调度到商业区夜间再平衡利用夜间低使用时段进行大规模车辆重新分配动态定价在供需失衡区域实施激励措施引导用户行为# 生成调度建议表 scheduling_suggestions pd.DataFrame({ source_grid: excess_supply.index.tolist(), target_grid: supply_shortage.index.tolist(), suggested_count: [min(abs(a), abs(b)) for a, b in zip(excess_supply.values, supply_shortage.values)] }) print(调度建议) print(scheduling_suggestions.sort_values(suggested_count, ascendingFalse).head(10))5.3 用户行为分析通过RFM模型最近一次消费Recency、消费频率Frequency、消费金额Monetary可以对用户进行分类# 计算RFM指标 now pd.to_datetime(2023-09-01) # 假设当前日期 rfm data.groupby(user_id).agg({ start_time: lambda x: (now - x.max()).days, # Recency bike_id: count, # Frequency duration: sum # Monetary (假设费用与时长相关) }).rename(columns{start_time: recency, bike_id: frequency, duration: monetary}) # RFM评分 rfm[r_score] pd.qcut(rfm[recency], 5, labels[5,4,3,2,1]) rfm[f_score] pd.qcut(rfm[frequency], 5, labels[1,2,3,4,5]) rfm[m_score] pd.qcut(rfm[monetary], 5, labels[1,2,3,4,5]) # 用户分类 def classify_user(row): if row[r_score] 4 and row[f_score] 4 and row[m_score] 4: return 高价值用户 elif row[r_score] 2 and row[f_score] 2 and row[m_score] 2: return 流失风险用户 else: return 一般用户 rfm[user_class] rfm.apply(classify_user, axis1) print(用户分类统计) print(rfm[user_class].value_counts())6. 工程化与部署为了使分析流程可复用我们可以将其封装为模块化的Pipelinefrom sklearn.pipeline import Pipeline from sklearn.base import BaseEstimator, TransformerMixin class DataCleaner(BaseEstimator, TransformerMixin): 数据清洗转换器 def fit(self, X, yNone): return self def transform(self, X): # 实现清洗逻辑 X X.copy() X[start_time] pd.to_datetime(X[start_time]) X[end_time] pd.to_datetime(X[end_time]) X[duration] (X[end_time] - X[start_time]).dt.total_seconds()/60 return X[(X[duration] 1) (X[duration] 240)] class FeatureEngineer(BaseEstimator, TransformerMixin): 特征工程转换器 def fit(self, X, yNone): return self def transform(self, X): # 实现特征工程逻辑 X X.copy() X[start_hour] X[start_time].dt.hour X[distance] X.apply(lambda x: haversine(x[start_lng], x[start_lat], x[end_lng], x[end_lat]), axis1) return X # 构建完整Pipeline pipeline Pipeline([ (cleaner, DataCleaner()), (feat_eng, FeatureEngineer()), ]) # 应用Pipeline processed_data pipeline.fit_transform(raw_data)对于大规模数据可以考虑使用Dask或PySpark进行分布式处理import dask.dataframe as dd # 使用Dask处理大型数据集 ddf dd.read_csv(large_bike_data_*.csv, parse_dates[start_time, end_time], dtype{user_id: str}) # 并行计算 result ddf.groupby(start_hour).size().compute()7. 实际应用案例7.1 城市热点区域识别通过对连续多天的数据进行分析可以识别城市的持久性热点区域# 计算每个网格的日均骑行量 daily_rides data.groupby([start_grid, data[start_time].dt.date]).size() hot_spots daily_rides.groupby(start_grid).mean().sort_values(ascendingFalse).head(10) print(城市骑行热点区域日均骑行量) print(hot_spots)7.2 节假日与平日模式对比比较节假日和平日的骑行模式差异# 标记节假日 holidays [2023-01-01, 2023-05-01] # 示例日期 data[is_holiday] data[start_time].dt.date.astype(str).isin(holidays) # 对比分析 holiday_pattern data[data[is_holiday]].groupby(start_hour).size() weekday_pattern data[~data[is_holiday] ~data[is_weekend]].groupby(start_hour).size() weekend_pattern data[data[is_weekend] ~data[is_holiday]].groupby(start_hour).size() plt.figure(figsize(12, 6)) plt.plot(holiday_pattern, label节假日, colorred) plt.plot(weekday_pattern, label工作日, colorblue) plt.plot(weekend_pattern, label周末, colorgreen) plt.legend() plt.title(不同日期类型的骑行模式对比) plt.xlabel(小时) plt.ylabel(骑行量) plt.grid() plt.show()7.3 天气因素影响分析结合天气数据如温度、降水分析外部因素对单车使用的影响# 假设已加载天气数据weather_df analysis_df data.merge(weather_df, left_ondata[start_time].dt.date, right_ondate) # 按天气分组分析 weather_impact analysis_df.groupby(weather_condition)[duration].mean() plt.figure(figsize(10, 5)) weather_impact.plot(kindbar, colorteal) plt.title(不同天气条件下的平均骑行时长) plt.ylabel(平均时长(分钟)) plt.xticks(rotation45) plt.grid(axisy) plt.show()8. 持续优化与迭代数据分析是一个持续优化的过程以下是一些改进方向数据增强整合POI数据、交通站点数据等外部数据源模型升级尝试使用机器学习模型预测需求实时处理构建流处理管道实现近实时分析可视化增强开发交互式仪表板供业务人员使用# 示例使用Prophet进行需求预测 from prophet import Prophet # 准备时间序列数据 hourly_demand data.groupby(pd.Grouper(keystart_time, freqH)).size().reset_index() hourly_demand.columns [ds, y] # 训练预测模型 model Prophet(seasonality_modemultiplicative) model.fit(hourly_demand) # 生成未来24小时预测 future model.make_future_dataframe(periods24, freqH) forecast model.predict(future) # 绘制预测结果 fig model.plot(forecast) plt.title(共享单车需求预测) plt.xlabel(时间) plt.ylabel(骑行量) plt.show()

相关新闻

坐标注意力 (CA) 模块 PyTorch 实现:3 步完成即插即用,提升分割模型 2% mIoU

坐标注意力 (CA) 模块 PyTorch 实现:3 步完成即插即用,提升分割模型 2% mIoU

坐标注意力模块(CA)的PyTorch实战指南:3步集成提升分割模型性能在图像分割任务中,注意力机制已经成为提升模型性能的关键技术。不同于传统的卷积操作平等对待所有空间位置,注意力机制能够动态调整不同区域的重要性权重…

2026/7/8 22:36:23 阅读更多 →
PyTorch 语义分割损失函数组合:Cross-Entropy + Dice Loss 的 2 种加权策略与效果对比

PyTorch 语义分割损失函数组合:Cross-Entropy + Dice Loss 的 2 种加权策略与效果对比

PyTorch 语义分割损失函数组合:Cross-Entropy Dice Loss 的 2 种加权策略与效果对比在语义分割任务中,类别不平衡和边界模糊是两大核心挑战。传统交叉熵损失(Cross-Entropy Loss)虽能有效衡量像素级分类误差,但对类别…

2026/7/8 22:36:23 阅读更多 →
MetaTube插件:Jellyfin和Emby媒体库的终极智能元数据解决方案

MetaTube插件:Jellyfin和Emby媒体库的终极智能元数据解决方案

MetaTube插件:Jellyfin和Emby媒体库的终极智能元数据解决方案 【免费下载链接】jellyfin-plugin-metatube MetaTube Plugin for Jellyfin/Emby 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-plugin-metatube 你是否厌倦了手动整理媒体库中杂乱无章…

2026/7/8 22:34:22 阅读更多 →

最新新闻

Browser Use 实战指南:AI 智能体浏览器自动化

Browser Use 实战指南:AI 智能体浏览器自动化

随着 AI 智能体开始从内容生成走向任务执行,浏览器自动化成为连接 AI 与 Web 应用的重要入口。但传统自动化工具依赖固定脚本和页面结构,当网站频繁更新或交互流程复杂时,维护成本不断增加。Browser Use 通过结合大语言模型和浏览器控制能力&…

2026/7/8 23:32:52 阅读更多 →
自动驾驶激光雷达标定:Apollo 9.0 动态标定实战,10km/h 绕圈采集与结果更新

自动驾驶激光雷达标定:Apollo 9.0 动态标定实战,10km/h 绕圈采集与结果更新

自动驾驶激光雷达动态标定实战:Apollo 9.0 10km/h绕圈采集全流程解析激光雷达作为自动驾驶系统的"眼睛",其标定精度直接决定了感知模块的可靠性。传统静态标定方法依赖专用场地和标定板,难以应对实际道路环境中的机械振动和温度漂移…

2026/7/8 23:32:52 阅读更多 →
激光雷达-相机联合标定:无靶标自动算法解析与3类环境特征应用

激光雷达-相机联合标定:无靶标自动算法解析与3类环境特征应用

激光雷达-相机联合标定:无靶标自动算法解析与3类环境特征应用当自动驾驶车辆行驶在复杂的城市环境中,激光雷达与相机的数据融合质量直接决定了感知系统的可靠性。传统标定方法依赖特定标定板,不仅操作繁琐,更难以应对车辆长期运行…

2026/7/8 23:32:52 阅读更多 →
MobileNetV3-Small 1.0 与 ShuffleNetV2 1.0x 移动端部署对比:ImageNet 精度与 3 款手机推理速度实测

MobileNetV3-Small 1.0 与 ShuffleNetV2 1.0x 移动端部署对比:ImageNet 精度与 3 款手机推理速度实测

MobileNetV3-Small 1.0 与 ShuffleNetV2 1.0x 移动端部署实战评测:精度、速度与内存占用全解析在移动端AI应用开发中,模型选型往往需要在精度、推理速度和内存占用之间寻找平衡点。本文将通过完整的Benchmark测试流程,对比分析MobileNetV3-Sm…

2026/7/8 23:30:50 阅读更多 →
轮式永磁吸附爬壁机器人 ADAMS 2023 运动仿真:菱形结构转向滑移率降低 15% 分析

轮式永磁吸附爬壁机器人 ADAMS 2023 运动仿真:菱形结构转向滑移率降低 15% 分析

轮式永磁吸附爬壁机器人 ADAMS 2023 运动仿真:菱形结构转向滑移率降低 15% 分析在工业检测领域,爬壁机器人正逐渐取代传统人工检测方式,成为储罐、船舶等大型钢结构表面检测的主力军。其中,轮式永磁吸附爬壁机器人因其结构简单、运…

2026/7/8 23:28:49 阅读更多 →
LVI-SAM 1.0 多传感器外参配置:3个关键参数详解与 4 类数据集适配实战

LVI-SAM 1.0 多传感器外参配置:3个关键参数详解与 4 类数据集适配实战

LVI-SAM 1.0 多传感器外参配置:3个关键参数详解与 4 类数据集适配实战当你在ROS环境下成功部署LVI-SAM后,真正的挑战才刚刚开始——如何让这套融合了视觉、激光雷达和IMU的SLAM系统在你的硬件平台上精准工作?本文将深入解析传感器外参配置这一…

2026/7/8 23:28:49 阅读更多 →

日新闻

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破

3大核心能力重塑《明日方舟》游戏体验:MAA自动化助手的革命性突破 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: …

2026/7/8 0:00:48 阅读更多 →
MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N+1 到批处理的全路径

MyBatis 批量操作深度优化——从 N1 到批处理的全路径 一、从"功能正确"到"性能可接受"——MyBatis 批量操作的三段式进化 MyBatis 在日常增删改查场景中几乎是无感的——实体映射直观、SQL 控制灵活。但当数据量从千级上升到十万级、百万级,许…

2026/7/8 0:00:48 阅读更多 →
工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

工业负载控制方案:TPD2015FN与PIC18F45K22应用解析

1. 工业负载控制方案概述在工业自动化、电机驱动和照明控制等高需求场景中,可靠地控制电感和电阻负载是核心挑战之一。TPD2015FN作为东芝的8通道高端智能功率开关IC,配合PIC18F45K22微控制器,能够构建一套稳定、高效的负载控制系统。这套组合…

2026/7/8 0:02:48 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/8 16:59:55 阅读更多 →

月新闻