Pandas自定义函数报错:无法将Series转为float,求多城市距离计算方案
问题描述
我创建了如下Pandas DataFrame:
import pandas as pd import numpy as np from math import sin, cos, sqrt, atan2, radians ds1 = {'Longitude':[-46.6736,-46.50926,-46.75166,-46.54743], "Latitude" : [-23.69057,-23.41165,-23.51482,-23.42598]} df1 = pd.DataFrame(data=ds1)
输出内容:
print(df1) Longitude Latitude 0 -46.67360 -23.69057 1 -46.50926 -23.41165 2 -46.75166 -23.51482 3 -46.54743 -23.42598
需要计算该DataFrame中每条记录到多个巴西城市的距离(单位:公里),这些城市的经纬度如下:
coordinates = { "rio" : [-23.02,-43.474889], "curitiba" : [-25.38792,-49.27741], "portoAlegre" : [-29.98115,-51.19597], "salvador" : [-12.97369,-38.43908], "manaus" :[-3.012972,-59.926802], "campoGrande" : [-20.52243,-54.58743], "beloHorizonte" : [-19.79722,-43.95691], "portoVelho" : [-8.774148,-63.851237], "recife" : [-8.12673,-34.90491], "boaVista" : [2.844999,-60.718089], "fortaleza" : [-3.76489,-38.51496], "rioBranco" : [-9.972341,-67.801294], "palmas" : [-10.165953,-48.880833], "natal" : [-5.79861,-35.18398], "aracaju" : [-10.972717,-37.068985], "teresina" : [-5.10247,-42.79552] }
距离计算函数如下:
def radius(latitude1, longitude1, latitude2, longitude2): R = 6373.0 lat1 = radians(latitude1) lon1 = radians(longitude1) lat2 = radians(latitude2) lon2 = radians(longitude2) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) distance = R * c return distance
尝试计算到里约热内卢的距离时:
df1['distanceFromRio'] = radius(coordinates["rio"][0],coordinates["rio"][1],df1['Latitude'],df1['Longitude'])
触发错误:
TypeError: cannot convert the series to <class 'float'>
希望避免使用数组/列表,直接为coordinates里的所有城市生成对应距离列(如distanceFromCuritiba、distanceFromPortoAlegre等),该怎么实现?
解决方案
1. 错误根源
原来用的math模块函数只支持单个浮点数,而Pandas Series是一组数值集合,直接传入会导致类型不匹配报错。需要改用支持向量化运算的numpy对应函数,这样就能直接处理整个Series。
2. 修改距离计算函数
把math的函数替换成numpy版本,让函数兼容Series输入:
def radius(latitude1, longitude1, latitude2, longitude2): R = 6373.0 lat1 = np.radians(latitude1) lon1 = np.radians(longitude1) lat2 = np.radians(latitude2) lon2 = np.radians(longitude2) dlon = lon2 - lon1 dlat = lat2 - lat1 a = np.sin(dlat / 2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2)**2 c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a)) distance = R * c return distance
3. 批量生成所有城市的距离列
遍历coordinates字典,对每个城市调用修改后的函数,直接生成对应列:
for city, (lat, lon) in coordinates.items(): # 格式化列名,比如rio -> distanceFromRio col_name = f"distanceFrom{city.capitalize()}" df1[col_name] = radius(lat, lon, df1['Latitude'], df1['Longitude'])
4. 查看结果
执行后,df1会自动新增16个距离列,每个列对应DataFrame中所有点到目标城市的公里数。可以用print(df1)查看完整结果。
内容的提问来源于stack exchange,提问作者Giampaolo Levorato
相关产品推荐
相关产品推荐

