使用 Pandas 数据帧的半正弦函数

问题描述

我是 Python 新手。我正在尝试在 Panda Dataframe 上计算haversine我有 2 个数据框。像这样:First 3 rows of first dataframe

第二个:First 3 rows of second dataframe

这是我的半正弦函数

    from math import radians,cos,sin,asin,sqrt

    def haversine(lon1,lat1,lon2,lat2):
      # convert decimal degrees to radians 
      lon1,lat2 = map(radians,[lon1,lat2])

      # haversine formula 
      dlon = lon2 - lon1 
      dlat = lat2 - lat1 
      a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
      c = 2 * asin(sqrt(a)) 
      r = 3956 # Radius of earth in kilometers.
      return c * r

我以第一个数据帧中的经度和纬度值为中心,并在地图上画了圆圈(我以半径为 1000m)。首先,我尝试将第二个数据帧中的所有 lon 和 lat 值与第一个数据帧中第一行中的 lon 和 lat 值一起提供给半正弦函数。然后我将对第一个数据框中的其他行执行相同的操作。因此,我将能够找出第二个数据帧中的坐标(经度和纬度值)是否位于第一个数据帧中具有中心经度和纬度值的圆圈中。当我这样使用时它有效:

a = haversine(29.023165,40.992752,28.844604,41.113586)
radius = 1.00 # in kilometer
if a <= radius:
    print('Inside the area')
else:
    print('Outside the area')

在我编写的代码中,我无法给出我想要的确切顺序。我的意思是我通过在第一个数据帧和第二个数据帧中给出所有 lon 和 lat 值来尝试我的代码,但从逻辑上讲这是错误的(或不必要的操作)。我尝试了下面的代码(我尝试了代码 Haversine Distance Calc using Pandas Data Frame "cannot convert the series to <class 'float'>")但它给出了一个错误:('LONGITUDE','occurred at index 0').

from math import radians,sqrt

def haversine(lon1,lat2):
    
    # convert decimal degrees to radians 
    lon1,lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 3956 # Radius of earth in kilometers.
    return c * r

iskeleler.loc['density'] = iskeleler.apply(lambda row: haversine(iskeleler['lon'],iskeleler['lat'],row['LONGITUDE'],row['LATITUDE']),axis=1)

你能帮我解决这个问题吗?提前致谢。

解决方法

您用来计算半正弦距离的代码在每个参数中接收一个浮点数,因此您确实需要为每个参数传递浮点数。在这种情况下,iskeleler['lon']iskeleler['lat'] 是系列。

这应该可以计算同一行坐标之间的距离:

iskeleler.loc['density'] = iskeleler.apply(lambda row: haversine(
    row['lon'],row['lat'],row['LONGITUDE'],row['LATITUDE']
),axis=1)

但是您正在寻找可能需要 for 循环的成对距离,这效率不高。试试sklearn.metrics.pairwise.haversine_distances

from sklearn.metrics.pairwise import haversine_distances

distance_matrix = haversine_distances(
    iskeleler[['lat','lon']],iskeleler[['LATITUDE','LONGITUDE']]
)

如果你更喜欢表格结构,那么:

distance_table = pd.DataFrame(
    distance_matrix,index=pd.MultiIndex.from_frames(iskeleler[['lat','lon']]),columns=pd.MultiIndex.from_frames(iskeleler[['LATITUDE','LONGITUDE']]),).stack([0,1]).reset_index(name='distance')

这是一个例子,有很多方法可以从矩阵创建数据框。