如何将合并为字符串的经纬度转换为浮点对适配haversine函数
解决
haversine函数调用时的ValueError: too many values to unpack问题 你遇到的这个错误核心原因很明确:你传给haversine函数的坐标参数是字符串类型,而不是函数期望的「两个浮点数组成的可迭代对象(元组/列表)」。当Python尝试把字符串拆成lat1, lon1时,会把字符串的每个字符当作一个元素,自然会出现「拆包元素数量远超预期2个」的报错。
为什么之前的转换方法没生效?
你用clean["gps"] = clean["latitude"].map(str) + "," + " " + clean["longitude"].map(str)把经纬度拼成了类似"55.652480000000004, 12.510514"的字符串。之后尝试的float()、ast.literal_eval()等方法,要么没有正确把字符串拆成两个浮点数,要么没有把结果转换成函数能识别的元组/列表格式,导致问题持续。
最优解决方案:直接生成浮点数坐标对(避免字符串转换)
与其先拼字符串再费劲转换,不如直接从源数据生成符合要求的坐标格式:
# 将latitude和longitude转为float后,用zip打包成元组列 clean["gps"] = list(zip(clean["latitude"].astype(float), clean["longitude"].astype(float)))
这样clean["gps"]中的每个元素都是(纬度浮点数, 经度浮点数)的元组,直接就能传入haversine函数,不需要任何额外转换。
如果已经生成了字符串类型的gps列,如何修复?
如果你已经有了那个拼接好的字符串列,可以用apply方法批量转换:
def str_to_coord(coord_str): # 去除首尾空格,按逗号拆分,再分别转成浮点数 lat_str, lon_str = coord_str.strip().split(',') return (float(lat_str.strip()), float(lon_str.strip())) # 转换整个gps列 clean["gps"] = clean["gps"].apply(str_to_coord)
转换后,每个元素就变成了haversine函数能直接处理的浮点数元组。
验证你的循环代码
另外要确保crimepoints字典中的coord值也是同样的浮点数元组格式(比如(51.5073219, -0.1276474)),避免因为另一边格式不匹配再出问题。
完整可运行示例
import pandas as pd import math def haversine(coord1, coord2): R = 6372800 # Earth radius in meters lat1, lon1 = coord1 lat2, lon2 = coord2 phi1, phi2 = math.radians(lat1), math.radians(lat2) dphi = math.radians(lat2 - lat1) dlambda = math.radians(lon2 - lon1) a = math.sin(dphi/2)**2 + \ math.cos(phi1)*math.cos(phi2)*math.sin(dlambda/2)**2 return 2*R*math.atan2(math.sqrt(a), math.sqrt(1 - a)) # 模拟你的数据 clean = pd.DataFrame({ "time": ["2019-02-15 15:32:00"], "latitude": [55.652480], "longitude": [12.510514] }) # 正确生成gps坐标列 clean["gps"] = list(zip(clean["latitude"].astype(float), clean["longitude"].astype(float))) # 模拟犯罪点数据 crimepoints = { "Central City": (55.650000, 12.510000), "West District": (55.700000, 12.550000) } crimelist = [] for n in clean["gps"]: print(n) for city, coord in crimepoints.items(): distance = haversine(n, coord) print(city, distance) if distance <= 500: print('alarm') print(distance) crimelist.append(city) crimelist.append(distance)
内容的提问来源于stack exchange,提问作者Georgi Ivanov Dimitrov
相关产品推荐
相关产品推荐

