PySpark中遍历DataFrame每行数据,基于轨迹列生成Folium地图折线的实现方法
PySpark中遍历DataFrame每行数据,基于轨迹列生成Folium地图折线的实现方法
嗨,我来帮你搞定这个问题!你不用纠结UDF啦——因为Folium是本地Python库,没法在Spark集群上运行,咱们直接把需要的数据拉到本地处理更简单,还能避开你遇到的那些坑。
核心实现步骤
首先理清思路:要给每个ID画轨迹折线,得先把Spark DataFrame里的相关数据拉到本地,再遍历每一行生成Folium折线。这里数据量控制是关键,不然会像你那样出现连接断开的错误。
- 导入依赖库
import folium from pyspark.sql import SparkSession
- 准备数据(先缩小范围避免内存溢出)
你的原始数据集可能很大,直接collect()会把所有数据拉到驱动节点,导致内存不足或者连接重置。所以先筛选、采样或者取前N行测试:
# 假设你已经创建了SparkSession spark = SparkSession.builder.appName("AIS_Data_Analysis").getOrCreate() # 读取数据后,先筛选需要的列,再限制数据量(比如取前100行) df_processed = df_pyspark.select("ID", "Trajectory", "types").limit(100) # 如果需要采样,可以用sample:df_processed = df_pyspark.select(...).sample(fraction=0.05)
- 生成Folium地图和折线
遍历处理后的数据集,提取每个ID的轨迹坐标,生成折线并添加到地图上:
# 初始化地图,用数据里的大致中心坐标(比如取第一个轨迹的坐标) first_row = df_processed.first() center_lat = first_row.Trajectory[0].Latitude center_lon = first_row.Trajectory[0].Longitude m = folium.Map(location=[center_lat, center_lon], zoom_start=10) # 遍历每一行生成折线 for row in df_processed.collect(): # 注意:Folium的坐标顺序是【经度, 纬度】,别搞反了! trajectory_coords = [[point.Longitude, point.Latitude] for point in row.Trajectory] # 生成tooltip内容,把types数组转成字符串 tooltip = f"ID: {row.ID}\n类型: {', '.join(row.types)}" # 创建折线并添加到地图 folium.PolyLine( locations=trajectory_coords, tooltip=tooltip, color="darkblue", weight=2, opacity=0.7 ).add_to(m) # 保存地图到本地HTML文件 m.save("ais_trajectory_map.html")
解决你遇到的collect()报错问题
你看到的ConnectionResetError是因为原始数据集太大,collect()会把集群上所有数据拉到你的本地驱动节点,超出了内存或者连接限制。解决办法有这些:
- 先过滤数据:比如根据
types筛选特定类型,或者按时间范围过滤,只保留需要的部分数据 - 用
limit(n)只取前n行做测试,确认逻辑没问题后再逐步扩大数据量 - 用
sample(fraction=x)采样部分数据(比如x=0.1就是取10%的数据) - 如果必须处理全量数据,可以用
foreachPartition分批次处理每个分区的数据,避免一次性拉取所有数据(不过这个需要调整代码逻辑,适合数据量极大的场景)
额外注意事项
- 坐标顺序:Folium严格使用【经度, 纬度】的顺序,和你数据里的
Longitude、Latitude对应,别写反了,不然折线会跑到奇怪的地方 - 轨迹为空的情况:如果某个ID的Trajectory是空数组,可以加个判断跳过,避免报错
- 样式自定义:你可以修改
color、weight、opacity这些参数,让不同类型的轨迹显示不同颜色,比如根据types里的内容设置颜色
备注:内容来源于stack exchange,提问作者Hygdrasil
相关产品推荐
相关产品推荐

