【问题标题】:How to apply the haversine function through loops of two pandas data frames of different sizes?如何通过两个不同大小的熊猫数据框的循环应用haversine函数?
【发布时间】:2020-03-09 17:51:50
【问题描述】:

我有两个不同大小的数据框 A(236 x 4) 和 B(967 x 4)。我想使用一个嵌套循环遍历两个数据帧的行,该循环接受两个 FIPS 列的输入,如果它们相等,我希望它们吐出一个半正弦距离。

一个数据框的头部是这样的,

       AddressClinic             CountyClinicFIPS       Lat               Lon\
 0  9137 ST.RT. 136, WEST UNION, OH, 45693   1.0   -83.60553     38.809795
 1  940 N. Cable Rd., Lima, OH, 45805        3.0   -84.14703     40.755620
 2  934 Center St. Ste E, Ashland, OH, 44805 5.0   -82.31091     40.859657  
 3  934 Center ST Ste. E, Ashland, OH, 44805 5.0   -82.31091     40.859657 
 4  3225 Lake Avenue, Ashtabula, OH, 44004   7.0   -80.79042     41.876133  

另一个数据帧格式完全相同,不同地址信息格式相同。

                InputAddr            CountyRetailerFIPS Lat         Lon\
   0     16782 ST RT 125, WEST UNION, OH, 45693  1 -83.41653   38.771553
   1      156 NORTH MAIN ST, PEEBLES, OH, 45660  1 -83.40529   38.949960  
   2       18811 SR 136 , WINCHESTER, OH, 45697  1 -83.65418   38.937350 
   3  2100 HARDING HIGHWAY #12, LIMA, OH, 45804  3 -84.06680   40.730656  
   4         1102 ELIDA AVE, DELPHOS, OH, 45833  3 -84.32622   40.842110  

我一直在尝试的代码是一个看起来像这样的almagmation

import pandas as pd
import numpy as np
from numpy import cos, sin, arcsin, sqrt
from math import radians

dataclinic=pd.read_csv(r"C:\Users\Jack\Documents\Schoolwork\WICResearch\MyDocs\getdistanceclinic.csv")
dataretailer=pd.read_csv(r"C:\Users\Jack\Documents\Schoolwork\WICResearch\MyDocs\getdistanceretailer.csv")
datadistance = pd.DataFrame([])

def haversine(row):
    lon1 = row1['Lon']
    lat1 = row1['Lat']
    lon2 = row2['Lon']
    lat2 = row2['Lat']
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * arcsin(sqrt(a)) 
    km = 6367 * c
    return km

for index1, row1 in dataclinic.iterrows():
    for index2, row2 in dataretailer.iterrows():
        if row1['CountyClinicFIPS'] == row2['CountyRetailerFIPS']:
            datadistance = datadistance.apply(lambda row: haversine(row), axis=1)
        else: 
            continue


print(datadistance)

不出所料,它不起作用。它有一些作用,但不多。它返回 datadistance 作为 (0,) index1,2 as int 235,966 row1,2 作为系列值 (4,) 的系列对象,它们都是数据帧第一行的元素。

预期的结果是使用 ClinicFips = RetailerFips 的所有案例填充 datadistance,并计算并列出两者之间的距离,以便更容易地在县之间进行平均。

也许我以错误的方式解决这个问题。任何意见是极大的赞赏。谢谢。

【问题讨论】:

    标签: python pandas loops iteration haversine


    【解决方案1】:

    我认为您应该先加入 2 个数据框。这将为您提供一个数据框,其中包含CountyClinicFIPS = CountyRetailerFIPS 的行。代码看起来像:

    df = pd.merge(dataclinic, dataretailter, left_on='CountyClinicFIPS', right_on='CountyRetailerFIPS', suffixes=['_clinic','_retailer'])
    

    然后使用像在这个答案中找到的那样的向量化实现 - Fast Haversine Approximation (Python/Pandas)。这将比逐行遍历数据帧并使用应用函数更快。

    harsine 代码看起来像这样(一旦您从上面的链接中导入了 haversine_np 函数):

    df['distance'] = haversine_np(df['lon_clinic'],df['lat_clinic'],df['lon_retailer'],df['lat_retailer'])
    

    希望这会有所帮助!

    【讨论】:

    • 谢谢,但我认为我没有很好地澄清我的意思。我希望 FIPS 行的值相等,而不是行本身。也许我遗漏了一些东西,但我看不出矢量化对这一点有什么帮助,因为如果有意义的话,我需要从一个点到具有相同 FIPS 标识符的所有其他点的距离。
    • 嗯,这就是我最初解释您的问题的方式。前任。让我们看看 CountyClinicFIPS = 1 的第一行。假设数据零售商中有 50 行 CountyRetailerFIPS = 1。那么你想要从县诊所到所有 50 家零售商的距离,对吗?
    • 没错。这就是为什么我认为嵌套循环将是要走的路。但也许这与该方法有关的观察太多。
    • 对,所以合并将完全完成您想要做的事情,而且它比嵌套循环快得多。这是合并功能的文档:pandas.pydata.org/pandas-docs/stable/reference/api/… 除非我误解了什么?
    • 您能否进一步解释一下合并将如何帮助我做到这一点?它会创建与地理点的所有组合来运行该功能吗?我需要的是在县内拥有相同 FIPS 名称的诊所和零售商的所有组合,这样我就可以从每个诊所到县内的每个零售商都有一段距离。抱歉,如果这令人困惑,到目前为止,我一直在努力向所有人解释我的问题。
    猜你喜欢
    • 2020-05-05
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 1970-01-01
    相关资源
    最近更新 更多