在python中计算经纬度点之间的距离时出错

Posted

技术标签:

【中文标题】在python中计算经纬度点之间的距离时出错【英文标题】:Error from calculating the distance between points with latitiude and longitude in python 【发布时间】:2021-06-09 22:31:36 【问题描述】:

我正在尝试用纬度和经度计算不同地理位置之间的距离(以公里为单位)。我尝试使用此线程中的代码:Pandas Latitude-Longitude to distance between successive rows。但是,我遇到了这个错误:

有人知道如何解决这个问题吗?

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~\Anaconda3\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
   5464                 return self[name]
-> 5465             return object.__getattribute__(self, name)
   5466 

AttributeError: 'Series' object has no attribute 'radians'

The above exception was the direct cause of the following exception:

TypeError                                 Traceback (most recent call last)
<ipython-input-56-3c590360590e> in <module>
     11 
     12 df['dist'] = haversine(df.latitude.shift(), df.longitude.shift(), 
---> 13                        df.loc[1:, 'latitude'], df.loc[1:, 'longitude'])
     14 
     15 

<ipython-input-56-3c590360590e> in haversine(lat1, lon1, lat2, lon2, to_radians, earth_radius)
      2 def haversine(lat1, lon1, lat2, lon2, to_radians=True, earth_radius=6371):
      3     if to_radians:
----> 4         lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])
      5 
      6     a = np.sin((lat2-lat1)/2.0)**2 + \

TypeError: loop of ufunc does not support argument 0 of type Series which has no callable radians method

这是数据框:

>>> df_latlon

    latitude    longitude
0   37.405548   -122.078481
1   34.080610   -84.200785
2   37.770830   -122.395463
3   37.773792   -122.409865
4   41.441269   -96.494304
5   41.441269   -96.494304
6   41.441269   -96.494304
7   41.883784   -87.637668
8   26.140780   -80.124434
9   39.960000   -85.983660

代码如下:

def haversine(lat1, lon1, lat2, lon2, to_radians=True, earth_radius=6371):
    if to_radians:
        lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + \
        np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2

    return earth_radius * 2 * np.arcsin(np.sqrt(a))


df_latlon['dist'] = haversine(df_latlon.latitude.shift(), df_latlon.longitude.shift(), 
                       df_latlon.loc[1:, 'latitude'], df_latlon.loc[1:, 'longitude'])


【问题讨论】:

【参考方案1】:

您将 Series 传递给 hasrsine 函数,而不是 lat 和 lon 属性的简单数字。

我认为您可以使用 apply 函数将 hasrsine 应用于数据框中的每一行,但是,我不太确定 apply 能够获得下一行或上一行的最佳方法是什么。

所以,我只需添加几个额外的列“来自 lat”和“来自 lon”。然后,您将在每一行中获得所需的所有数据。

# add the from lat and lon as extra columns
df_latlon['from lat'] = df_latlon['latitude'].shift(1)
df_latlon['from lon'] = df_latlon['longitude'].shift(1)

def calculate_distance(df_row):
    return haversine(df_row['from lat'], df_row['from lon'], df_row['latitude'], df_row['longitude'])

# pass each row through the haversine function via the calculate_distance
df_latlon['dist'] = df_latlon.apply(calculate_distance, axis=1)

【讨论】:

【参考方案2】:

我认为问题是您想逐行计算,但是将系列发送到函数中似乎不起作用。

试试:

data='''
    latitude    longitude
0   37.405548   -122.078481
1   34.080610   -84.200785
2   37.770830   -122.395463
3   37.773792   -122.409865
4   41.441269   -96.494304
5   41.441269   -96.494304
6   41.441269   -96.494304
7   41.883784   -87.637668
8   26.140780   -80.124434
9   39.960000   -85.983660'''
df = pd.read_csv(io.StringIO(data), sep='  \s+', engine='python')
df[['lat2', 'lon2']] = df[['latitude', 'longitude']].shift()


def haversine(lat1, lon1, lat2, lon2, to_radians=True, earth_radius=6371):
    if to_radians:
        lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + \
        np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2

    return earth_radius * 2 * np.arcsin(np.sqrt(a))

df_latlon['dist'] = df.apply(lambda x: haversine(x['lat2'], x['lon2'], x['latitude'], x['longitude']), axis=1)

    latitude   longitude       lat2        lon2         dist
0  37.405548 -122.078481        NaN         NaN          NaN
1  34.080610  -84.200785  37.405548 -122.078481  3415.495909
2  37.770830 -122.395463  34.080610  -84.200785  3439.656694
3  37.773792 -122.409865  37.770830 -122.395463     1.307998
4  41.441269  -96.494304  37.773792 -122.409865  2248.480322
5  41.441269  -96.494304  41.441269  -96.494304     0.000000
6  41.441269  -96.494304  41.441269  -96.494304     0.000000
7  41.883784  -87.637668  41.441269  -96.494304   737.041395
8  26.140780  -80.124434  41.883784  -87.637668  1880.578726
9  39.960000  -85.983660  26.140780  -80.124434  1629.746292

【讨论】:

以上是关于在python中计算经纬度点之间的距离时出错的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 从导入的 csv 计算纬度/经度点之间的距离?

Python 优雅地利用两点经纬度计算地理空间距离

Python 优雅地利用两点经纬度计算地理空间距离

计算两个经纬度点之间的距离? (Haversine 公式)

如何计算经纬度之间的距离?

如何计算两个经纬度之间的距离[重复]