python 中经纬度点间距离计算错误
Error from calculating the distance between points with latitiude and longitude in python
我正在尝试计算具有纬度和经度的不同地理位置之间的距离(以公里为单位)。我尝试使用此线程中的代码:。然而,我运行进入这个错误:
有谁知道如何解决这个问题?
---------------------------------------------------------------------------
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'])
您正在将系列传递给半正弦函数,而不是 lat 和 lon 属性的简单数字。
我认为您可以使用 apply 函数将 haversine 应用于数据框中的每一行,但是,我不太确定 apply 能够获取下一个或上一个的最佳方法是什么行。
因此,我将添加几个额外的列 'from lat' 和 'from 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)
我认为问题是您想要逐行计算,但是将系列发送到函数中似乎不起作用。
尝试:
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
我正在尝试计算具有纬度和经度的不同地理位置之间的距离(以公里为单位)。我尝试使用此线程中的代码:
有谁知道如何解决这个问题?
---------------------------------------------------------------------------
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'])
您正在将系列传递给半正弦函数,而不是 lat 和 lon 属性的简单数字。
我认为您可以使用 apply 函数将 haversine 应用于数据框中的每一行,但是,我不太确定 apply 能够获取下一个或上一个的最佳方法是什么行。
因此,我将添加几个额外的列 'from lat' 和 'from 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)
我认为问题是您想要逐行计算,但是将系列发送到函数中似乎不起作用。
尝试:
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