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

使用GeoPandas计算地址间距离时遇TypeError问题求助

排查步骤及解决方案

1. 检查经纬度数据类型

TypeError最常见的触发原因是经纬度列不是数值类型。先确认DataFrame中lat和lon列的类型:

print(df[['lat', 'lon']].dtypes)

如果输出为object(字符串类型),先转换为数值:

df['lat'] = pd.to_numeric(df['lat'], errors='coerce')
df['lon'] = pd.to_numeric(df['lon'], errors='coerce')

转换后检查缺失值(无法转换的内容会被转为NaN),并处理:

# 查看缺失值数量
print(df[['lat', 'lon']].isna().sum())
# 删除含缺失值的行
df = df.dropna(subset=['lat', 'lon'])

2. 确认Shapely Point的参数顺序

Shapely的Point构造函数要求参数顺序为**(经度, 纬度)**(x轴对应经度,y轴对应纬度),如果搞反成(纬度, 经度),不仅会导致距离计算错误,若目标地址与DataFrame中Point的参数顺序不一致,也可能触发类型相关的隐性错误。

正确创建Point的方式:

from shapely.geometry import Point

# 目标地址:经度在前,纬度在后
target_point = Point(target_lon, target_lat)

# DataFrame中批量创建Point
df['point'] = df.apply(lambda row: Point(row['lon'], row['lat']), axis=1)

3. 验证目标地址的Point对象有效性

确保target_address是有效的shapely.geometry.Point实例,而非字符串、元组等其他类型:

# 错误示例:传入非Point类型
target_address = "34.0522, -118.2437"  # 字符串
target_address = (34.0522, -118.2437)  # 元组

# 正确示例
target_lon = -118.2437
target_lat = 34.0522
target_address = Point(target_lon, target_lat)

4. 正确计算地理英里距离

Shapely原生的distance()方法计算的是平面笛卡尔距离,并非真实地理距离。要得到英里数,需用地理坐标系计算球面距离:

方法一:用geopy(简洁直观)

from geopy.distance import geodesic

# 目标地址以(纬度, 经度)元组传入
target_coords = (target_lat, target_lon)

# 批量计算英里距离
df['distance_miles'] = df.apply(lambda row: geodesic(target_coords, (row['lat'], row['lon'])).miles, axis=1)

方法二:用pyproj+shapely(自定义性更强)

from pyproj import Geod
from shapely.geometry import Point

# 使用WGS84椭球体
geod = Geod(ellps='WGS84')

def calc_miles(target_point, row_point):
    # 计算米距后转换为英里
    _, _, dist_meters = geod.inv(target_point.x, target_point.y, row_point.x, row_point.y)
    return dist_meters * 0.000621371

df['distance_miles'] = df['point'].apply(lambda p: calc_miles(target_address, p))

5. 定位具体错误行

若以上步骤仍未解决问题,添加调试代码找到触发错误的具体数据行:

def safe_create_point(row):
    try:
        return Point(row['lon'], row['lat'])
    except TypeError as e:
        print(f"错误行索引: {row.name} | 错误信息: {e}")
        print(f"纬度值/类型: {row['lat']} | {type(row['lat'])}")
        print(f"经度值/类型: {row['lon']} | {type(row['lon'])}")
        return None

df['point'] = df.apply(safe_create_point, axis=1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:57:28