大家好!希望你一切顺利。我有一个代码,可以使用它们的地理坐标计算机场方向之间的距离。当我手动键入坐标时,代码运行良好。但是,当您使用panda从文件中获取输入时,会出现一些错误。我在不同的网站上搜索过如何修复它。人们都在键入更改为.astype(float(,但无济于事。我也把点改成了逗号,但也没用。我已经坚持了,请给我一些指导,建议吗?非常感谢。代码如下:
from math import radians, degrees, sin, cos, asin, acos, sqrt
import pandas as pd
df=pd.read_excel('coordinates.xlsx', names=['from', 'long1','lat1','to','long2','lat2'], index = False)
def great_circle(lon1, lat1, lon2, lat2):
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
return 6371 * (
acos(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon1 - lon2))
)
great_circle(df['long1'], df['lat1'],df['long2'], df['lat2'])
错误:TypeError: cannot convert the series to <class 'float'>
从如下文件输入:
from long1 lat1 to long2 lat2
0 AKX 57.206667 50.245833 FRU 74.477556 43.061306
1 AKX 57.206667 50.245833 GUW 51.821389 47.121944
您的变量lat1、lat2-lon1-lon2属于Series
类型。如果在它们上应用sin,它将不起作用,那么sin
函数仅适用于数字输入。查看Python官方文档。
一般来说,当使用向量(pandas
中的Series
(或矩阵(pandas
、DataFrame
、numpy(时,运算符可能不同,这仅仅是因为输入不同于通常的运算符(Float
、Int
、String
与Vector(。
只需这样修改您的代码:
sin(lat1)
通过
lat1.apply(lambda x: sin(x))
整个代码将如下所示:
def parse_row(row):
result = 6371 * acos(row['sin_lat1'] * row['sin_lat2'] + row['cos_lat1'] * row['cos_lat2'] + row['cos_diff'])
return result
sin_lat1 = df['lat1'].apply(lambda x: sin(x)).reset_index()
sin_lat2 = df['lat2'].apply(lambda x: sin(x)).reset_index()
cos_lat1 = df['lat1'].apply(lambda x: cos(x)).reset_index()
cos_lat2 = df['lat2'].apply(lambda x: cos(x)).reset_index()
lon_diff = df['long1'] - df['long2']
cos_diff = lon_diff.apply(lambda x: cos(x)).reset_index()
df = pd.DataFrame(columns=['sin_lat1', 'sin_lat2', 'cos_lat1', 'cos_lat2', 'cos_diff'])
df['sin_lat1'] = sin_lat1
df['sin_lat2'] = sin_lat2
df['cos_lat1'] = cos_lat1
df['cos_lat2'] = cos_lat2
df['cos_diff'] = cos_diff
new_df = df.applymap(parse_row,axis=1)
有了这个,并应用于您的数据:
from long1 lat1 to long2 lat2
0 AKX 57.206667 50.245833 FRU 74.477556 43.061306
1 AKX 57.206667 50.245833 GUW 51.821389 47.121944
我得到了结果:
0 0.0
1 3.0
您也可以在numpy:中使用三角运算符
sin
我不完全确定你想要的准确度是多少,但vincenty方法的准确度更好(准确度在1毫米以内或更好!(。
如果你只是想把它插入你的代码中,这个包可能值得一试!
from vincenty import vincenty
boston = (42.3541165, -71.0693514)
newyork = (40.7791472, -73.9680804)
vincenty(boston, newyork)
>>> 298.396057
您甚至可以从geopy
模块中查看vincenty
!
(对不起,这不是你问题的直接答案,但是,你似乎已经找到了现有问题的答案!(