You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Folium世界地图批量标记点位报错KeyError: 'lat,lon'求助

解决Folium批量绘制标记时的KeyError: 'lat,lon'问题

错误原因

你遇到的KeyError: 'lat,lon',大概率是这两个问题之一:

  1. 你的DataFrame里没有单独的lat(纬度)和lon(经度)列,反而把经纬度合并成了一个名为lat,lon的列;
  2. 调用Folium方法时,错误地用'lat,lon'作为列名参数,而实际DataFrame里的列名是分开的lat和lon。

下面针对你提到的两种数据来源方式,分别给出正确的实现步骤:


方式一:字典创建DataFrame批量加标记

确保字典里的lat和lon是独立的键,对应各自的数值列表,不要合并在一起:

import folium
import pandas as pd

# 构造正确格式的数据源
person_data = {
    '姓名': ['张三', '李四', '王五'],
    '职位': ['后端工程师', 'UI设计师', '产品经理'],
    '年龄': [28, 32, 29],
    'lat': [39.9042, 31.2304, 23.1291],  # 单独的纬度列
    'lon': [116.4074, 121.4737, 113.2644] # 单独的经度列
}

# 转成DataFrame
df = pd.DataFrame(person_data)

# 初始化地图(中心设为中国区域,可按需调整)
world_map = folium.Map(location=[30, 110], zoom_start=4)

# 循环遍历每一行数据,添加标记和弹窗
for _, row in df.iterrows():
    # 构造弹窗内容,用HTML换行更清晰
    popup_text = f"""
    姓名: {row['姓名']}<br>
    职位: {row['职位']}<br>
    年龄: {row['年龄']}
    """
    # 创建标记并添加到地图
    folium.Marker(
        location=[row['lat'], row['lon']],
        popup=folium.Popup(popup_text, max_width=300)  # 设置弹窗宽度避免内容截断
    ).add_to(world_map)

# 保存地图为HTML文件
world_map.save('birth_place_map.html')

方式二:读取CSV文件批量加标记

情况1:CSV里已有单独的lat和lon列

如果你的CSV结构是这样的(列名分别为姓名、职位、年龄、lat、lon):

姓名,职位,年龄,lat,lon
张三,后端工程师,28,39.9042,116.4074
李四,UI设计师,32,31.2304,121.4737
王五,产品经理,29,23.1291,113.2644

直接读取后,用和上面一样的循环添加标记即可:

import folium
import pandas as pd

# 读取CSV
df = pd.read_csv('birth_data.csv')

# 初始化地图
world_map = folium.Map(location=[30, 110], zoom_start=4)

# 批量添加标记(代码和方式一的循环部分完全一致)
for _, row in df.iterrows():
    popup_text = f"""
    姓名: {row['姓名']}<br>
    职位: {row['职位']}<br>
    年龄: {row['年龄']}
    """
    folium.Marker(
        location=[row['lat'], row['lon']],
        popup=folium.Popup(popup_text, max_width=300)
    ).add_to(world_map)

world_map.save('birth_place_map.html')

情况2:CSV里经纬度是合并在一个列里

如果你的CSV里经纬度是合并成一个列(比如列名叫lat_lon,内容格式为39.9042,116.4074),需要先拆分列:

import folium
import pandas as pd

df = pd.read_csv('birth_data.csv')

# 拆分合并的经纬度列,生成单独的lat和lon列
df[['lat', 'lon']] = df['lat_lon'].str.split(',', expand=True)
# 把字符串类型的经纬度转成数值类型
df['lat'] = pd.to_numeric(df['lat'])
df['lon'] = pd.to_numeric(df['lon'])

# 后续添加标记的代码和上面一致
world_map = folium.Map(location=[30, 110], zoom_start=4)
for _, row in df.iterrows():
    popup_text = f"""
    姓名: {row['姓名']}<br>
    职位: {row['职位']}<br>
    年龄: {row['年龄']}
    """
    folium.Marker(
        location=[row['lat'], row['lon']],
        popup=folium.Popup(popup_text, max_width=300)
    ).add_to(world_map)

world_map.save('birth_place_map.html')

额外提示

如果你用的是Folium的批量插件(比如FastMarkerCluster),一定要指定正确的列名参数,比如:

from folium.plugins import FastMarkerCluster

# 用zip把lat和lon打包成坐标列表,再传入插件
FastMarkerCluster(
    data=list(zip(df['lat'], df['lon'])),
    popup=folium.Popup("弹窗内容", max_width=300)
).add_to(world_map)

内容的提问来源于stack exchange,提问作者Lambohihi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 17:01:10