【问题标题】:Calculate Euclidean distance of ATMs计算 ATM 的欧几里得距离
【发布时间】:2020-11-29 10:23:49
【问题描述】:

enter image description here

我需要按银行(clean_name)对自动取款机进行分组,并计算特定银行内每个自动取款机的距离,并找到最大欧几里得距离。

不确定如何将欧式函数应用于 groupby 并输出最大欧式距离

【问题讨论】:

  • 你能展示一些你试过的源代码吗?欧几里得距离的参考点在哪里?你有什么样的数据?数据框?
  • import numpy as np from scipy import spatial atm_number=df.groupby('clean_name')['objectid'].count() def not_one_atm(s): return atm_number[s]>1 df[ 'more_than_one_atm']=df['clean_name'].map(one_atm) bank_distance=df[['clean_name','x','y']][df['more_than_one_atm']] print(bank_distance) distance_rank=bank_distance。 groupby('clean_name').apply(lambda x: spatial.distance.pdist(np.array(list(zip(xx, xy)))).max()) distance_rank.sort_values(ascending=False)[0:10 ]
  • 我得到了答案,但我必须下载一个包来计算欧几里得距离。这对我来说真的没有意义。我的教授可能要求我们提供自定义 aggfunc。

标签: python-3.x pandas-groupby euclidean-distance


【解决方案1】:

欧几里得计算如下(运行片段):

<img src="https://wikimedia.org/api/rest_v1/media/math/render/svg/4febdae84cbc320c19dd13eac5060a984fd438d8" class="mwe-math-fallback-image-inline" aria-hidden="true" style="vertical-align: -1.671ex; width:35.907ex; height:4.843ex;" alt="{\displaystyle d(\mathbf {p} ,\mathbf {q} )={\sqrt {(q_{1}-p_{1})^{2}+(q_{2}-p_{2})^{2}}}.}">

对银行名称(clean_name)进行排序,然后使用上述公式计算银行与 ATM 之间的距离。

【讨论】:

    【解决方案2】:

    所以我不确定这是否是您预期的结果。我生成了从 ATM0 到 ATM100 的随机 ATM 名称的随机 ATM 位置。

    """Test Values"""
    import pandas as pd
    import numpy as np
    
    atms = {
        'clean_name' : ['ATM'+str(int(round(i*100))) for i in np.random.rand(300)],
        'x': np.random.rand(300)*100000,
        'y': np.random.rand(300)*100000
    }
    df = pd.DataFrame(atms)
    

    我按照您在评论中所做的那样对银行进行了分组,并等待用户输入搜索的 ATM:

    atm_df = df.groupby('clean_name') #Group
    
    """User-Interface"""
    atms = atm_df.groups.keys() #Get all available atm names
    atm_name = ''
    
    while atm_name not in atms:
        atm_name = input()
    
    used_atms = atm_df.get_group(atm_name)
    print("Used-ATM: {}\nAvailables ATMS: {}".format(atm_name, len(used_atms)))
    

    您需要插入 ATM 的名称。在我的(随机)示例中是输入“ATM10”,输出如下所示:

    ATM10
    Used-ATM: ATM10
    Availables ATMS: 3
    

    然后我们需要得到欧几里得测量的起始位置(这可以是具有 x 和 y 值的任何位置)

    start_pos = {'x': 50000, 'y': 50000}
    
    def euclidean(d_x, d_y, s_x, s_y): 
        return np.sqrt([(d_x-s_x)**2 + (d_y - s_y)**2]).tolist()[0] #euclidean distance function with destination (d) and start (s)
    

    然后你计算距离并返回最大值

    used_atms['distance'] = euclidean(used_atms['x'], used_atms['y'], start_pos['x'], start_pos['y'])
    max_atm =  used_atms.loc[used_atms['distance'].idxmax()] #max-distance
    

    如果你想说明 atms 你可以按照这个源代码:

    import matplotlib.pyplot as plt
    
    #line from start to destination
    lines_x = [start_pos['x'], max_atm['x']]
    lines_y = [start_pos['y'], max_atm['y']]
    
    fig, ax = plt.subplots()
    
    #Plot all Datapoints
    ax.scatter(df['x'], df['y'])
    ax.scatter(start_pos['x'], start_pos['y'], color='r')
    ax.scatter(used_atms['x'], used_atms['y'], color='cyan')
    
    #Plot the line
    ax.plot(lines_x, lines_y, color='r')
        
    plt.show()
    plt.savefig("atms.png")
    

    结果如下所示:

    更多问题。请更准确,发布您的源代码(不可在 cmets 中重复使用)

    【讨论】: