【问题标题】:How to join two dataframes in pandas using coordinates如何使用坐标连接熊猫中的两个数据框
【发布时间】:2016-08-26 15:31:42
【问题描述】:

我有两个坐标为archivo1 和archivo2 的数据帧,我需要第一个数据帧中第二个数据帧的最近点(id)。到目前为止,我的代码是:

import pandas as pd
import numpy as np

def getDistance(archivo1,lat,log):
  R = 6371 
  archivo1['dLat'] =(lat-archivo1['lat']).apply(deg2rad)/2
  archivo1['dLon'] =(log-archivo1['log']).apply(deg2rad)/2
  archivo1['a']=(archivo1['dLat'].apply(math.sin))*(archivo1['dLat'].apply(math.sin))+(archivo1['lat'].apply(deg2rad).apply(math.cos))*(math.cos(deg2rad(lat)))*(archivo1['dLon'].apply(math.sin))*(archivo1['dLon'].apply(math.sin))
  archivo1['b']=  archivo1['a'].apply(math.sqrt)/(1-archivo1['a'].apply(math.sqrt))
  archivo1['Distancia']=R*2*archivo1['b'].apply(math.atan)

def deg2rad(deg):
    return deg * (math.pi/180)

for i in range(len(archivo1)):
    getDistance(archivo1,archivo2['lat'].iloc[i],archivo2['long'].iloc[i])
    archivo1['id'].iloc[i]=str(archivo2[archivo2['Distancia']==archivo2['Distancia'].min()]['id'].iloc[0])

代码运行并给了我预期的结果,但是第一个文件有 700 万,第一个文件有 70k,所以需要 7 天的运行时间。谁能帮我优化一下?

这是两个文件的示例:

这是要查找的文件 2:

File 2:
id longitude latitude                  
L10F10P1    -72.61521393    8.290479554
L10F10P10   -72.61517542    8.290583772
L10F10P100  -72.61481425    8.290812192
L10F10P101  -72.61484522    8.290877898
L10F10P102  -72.61488579    8.290968212
L10F10P103  -72.61492075    8.291033898
L10F10P104  -72.61495586    8.291095669
L10F10P105  -72.61499304    8.291166076
L10F10P106  -72.61503357    8.291235121
L10F10P107  -72.61508271    8.291330912
L10F10P108  -72.61516194    8.291456605
L10F10P109  -72.61519939    8.291548893
L10F10P11   -72.61522969    8.290676982
L10F10P110  -72.61522794    8.291592503
[76701 rows x 9 columns]
File 1:
latitude longitude 
8.318648471 -72.6132329
8.318648678 -72.6134567
8.318648971 -72.6133456
8.318678421 -72.6138765
8.319765345 -72.6137658
[6877229 rows x 10 columns]

【问题讨论】:

  • 谢谢,你的代码需要我 4 分钟来记录 100 条记录,而我的需要 47 秒。
  • 你能举个例子吗?
  • 我认为您的最后一行可以通过使用 argmin 或 idxmin 来改进。
  • 我包含了这两个文件的一个小样本,我将尝试使用 idxmin。

标签: pandas join optimization coordinates closest-points


【解决方案1】:

如果没有示例,我不会编写确切的代码,而是逐行提出改进建议。一般的想法是apply 通常很慢,因为它本质上是一个幕后循环。


这肯定很慢:

archivo1['dLat'] = (lat-archivo1['lat']).apply(deg2rad)/2

这样会更好:

archivo1['dLat'] = (lat-archivo1['lat']) * math.pi/180/2

使用numpy 函数而不是应用math 函数也应该更快:

np.sin(archivo1['dLat'].values)

而不是

archivo1['dLat'].apply(math.sin)

values 属性使您可以访问底层的numpy 数组。同样,使用np.sqrt


然后在上面计算的numpy 数组上重复使用np.multiply 以逐元素相乘。您可以将最终数组分配回数据框的列Distancia


for 循环可以通过定义一个包含循环内两行的函数来改进,并使用apply 将其应用于数据帧中的每一行。


最后,使用argminidxmin 应该比:

archivo2[archivo2['Distancia']==archivo2['Distancia'].min()]

通过将以上所有内容放在一起,您应该已经看到了相当大的进步!

【讨论】:

  • 在 100 条记录样本中,它将时间从 47 秒减少到 21 秒。非常感谢
  • 如果您仍在寻求改进,您应该再次提出新问题(使用新代码)。它应该比星期五下午受到更多的关注,也许有人会有一个全新的想法,而不是我建议的逐步改进。同时您可以接受我的回答,您将获得 2 声望 ;)
猜你喜欢
  • 2019-06-26
  • 2013-08-14
  • 2015-08-15
  • 2021-05-11
  • 2020-10-13
  • 2022-10-06
  • 2018-09-13
  • 2016-03-13
相关资源
最近更新 更多