计算两点坐标距离遇错求助:TypeError与ValueError排查及解决
问题分析与解决方案
我来帮你拆解这两个错误的原因,再给出能直接运行的解决办法:
第一个错误:TypeError: cannot convert the series to <class 'float'>
错误原因
你用的是Python内置的math.radians()函数,这个函数只能处理单个浮点数,但你直接把一整列(pandas Series)传进去了,它没办法批量处理整个序列,所以就报错了。
解决办法
改用NumPy的np.radians(),它支持向量化操作,可以直接处理整个Series:
import numpy as np df_post['lat1'] = np.radians(df_post['pickup_lat']) df_post['lon1'] = np.radians(df_post['pickup_lon']) df_post['lat2'] = np.radians(df_post['dropoff_lat']) df_post['lon2'] = np.radians(df_post['dropoff_lon'])
之后你就可以用Haversine公式批量计算距离了,比如:
# Haversine公式实现(单位:公里) R = 6371 # 地球半径,单位公里 dlat = df_post['lat2'] - df_post['lat1'] dlon = df_post['lon2'] - df_post['lon1'] a = np.sin(dlat/2)**2 + np.cos(df_post['lat1']) * np.cos(df_post['lat2']) * np.sin(dlon/2)**2 c = 2 * np.arcsin(np.sqrt(a)) df_post['distance_km'] = R * c # 转成英里的话除以1.60934 df_post['distance_miles'] = df_post['distance_km'] / 1.60934
第二个错误:ValueError: When creating a Point from sequence, it must not have more than 3 items.
错误原因
geopy.distance.VincentyDistance()(注意这个方法现在已经被官方废弃了)需要接收单个的坐标点对(比如两个(lat, lon)元组),但你直接把整个pickup_coord和dropoff_coord列传进去了,它会把整个Series当成一个序列来解析,自然不符合参数要求。
解决办法
用pandas的apply()方法逐行处理每一对坐标,同时换成geopy推荐的geodesic()或distance()方法(这两个是VincentyDistance的替代方案,计算更准确):
from geopy import distance # 逐行计算距离,返回英里数 df_post['pickup_dropoff_distance'] = df_post.apply( lambda row: distance.geodesic(row['pickup_coord'], row['dropoff_coord']).miles, axis=1 )
如果你的pickup_coord和dropoff_coord还没生成,也可以直接用经纬度列计算,不用先转成元组:
df_post['pickup_dropoff_distance'] = df_post.apply( lambda row: distance.geodesic( (row['pickup_lat'], row['pickup_lon']), (row['dropoff_lat'], row['dropoff_lon']) ).miles, axis=1 )
总结
- 用Haversine公式的话,记得用NumPy的向量化函数,别用Python内置的math模块函数;
- 用geopy的话,一定要用
apply()逐行处理,不要直接传整个Series,同时尽量用新版本推荐的geodesic()方法。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

