我尝试计算2个位置之间的距离,但是此公式有误
acos(sin(latA)*sin(latB) + cos(latA)*cos(latB)*cos(abs(longB-longA)))
这是我计算距离的功能:
def distanceGPS(latA, longA, latB, longB):
"""Retourne la distance en Kilomètres entre les 2 points A et B connus grâce à
leurs coordonnées GPS (en radians).
"""
latA, longA, latB, longB = deg2rad(latA, longA, latB, longB)
print(latA)
print(longA)
print(latB)
print(longB)
# Rayon de la terre en mètres (sphère IAG-GRS80)
RT = 6378.137
# angle en radians entre les 2 points
S = acos(sin(latA)*sin(latB) + cos(latA)*cos(latB)*cos(abs(longB-longA)))
# distance entre les 2 points, comptée sur un arc de grand cercle
return (S*RT)
打印结果:
lat 0.651706
dtype: float64
lon -0.079956
dtype: float64
0.6517058798628295
-0.07995634999527296
这是我将度数转换为弧度的函数:
def deg2rad(latA, longA, latB, longB):
"""Convertit un angle "degrés décimaux" en "radians"
"""
return latA/180*pi, longA/180*pi, latB/180*pi, longB/180*pi
def test_prediction(corpus, lat_moy, long_moy, i):
"""
Cette fonction test si la localisation predite est a une distance inferieure a 100km de la localisation correct.
Si oui, alors on defini la prediction comme correct
Si non, alors on defini la prediction comme non correct
"""
for word in corpus.correct_localisation[i]:
loc = geolocator.geocode(word)
if loc is not None and distanceGPS(lat_moy, long_moy, loc.latitude, loc.longitude) <= 100:
corpus.at[i, "test_pred"] = "OK"
return
else:
corpus.at[i, "test_pred"] = "NOK"
return
我的错误是:
> --------------------------------------------------------------------------- ValueError Traceback (most recent call
> last) <ipython-input-18-75f41b231cbd> in <module>
> 11 df = coordonnees_article(corpus['article'][i])
> 12 lat_moy, long_moy = position_moyenne(outliers_coordonnees(df))
> ---> 13 test_prediction(corpus, lat_moy, long_moy, i)
> 14 print(i)
>
> <ipython-input-17-47270c034d33> in test_prediction(corpus, lat_moy,
> long_moy, i)
> 11 print(loc)
> 12 # try:
> ---> 13 if loc is not None and distanceGPS(lat_moy, long_moy, loc.latitude, loc.longitude) <= 100:
> 14 corpus.at[i, "test_pred"] = "OK"
> 15 return
>
> <ipython-input-16-129df29f0484> in distanceGPS(latA, longA, latB,
> longB)
> 13 RT = 6378.137
> 14 # angle en radians entre les 2 points
> ---> 15 S = acos(sin(latA)*sin(latB) + cos(latA)*cos(latB)*cos(abs(longB-longA)))
> 16
> 17 # distance entre les 2 points, comptée sur un arc de grand cercle
>
> ValueError: math domain error
谢谢您的帮助
答案 0 :(得分:2)
对于您有时会遇到的“怪异”情况,这是由于浮点数不准确所致。 例如,如果您运行:
1.2 - 1.0 = 0.19999999999999996
我们显然希望它表示为0.2,但是由于表示浮点数的方式(使用固定数目的二进制数字),我们得到了上面的结果。
您该如何处理?您可以使用decimal module或将值四舍五入到小数位数。
如果您在python中使用十进制模块:
from decimal import *
# the following sets the number of decimal places to 8
getcontext().prec = 8
# if you run
sin(latA)*sin(latB) + cos(latA)*cos(latB)*cos(abs(longB-longA))
# the output is
0.999999999999954
# if you use the decimal module
# (please note I am multiplying by 1 at the end)
Decimal(sin(latA)*sin(latB) + cos(latA)*cos(latB)*cos(abs(longB-longA)))*1
# the output is
Decimal('1.00000000000')
您还可以使用舍入功能并将数字舍入到更少的小数位:
x = 0.19999999999999996
round(x,8)
# the output is
0.2
在您的情况下,尽管我没有收到域错误,但我认为得到该错误的原因是因为您的计算机可能会计算出1.000000000004的值(例如)。因此,当您尝试使用 acos(1.0000000004)时,会出现域错误。在调用 acos 之前,使用上述两种方法对“答案”进行“四舍五入”可能会解决您面临的问题。