如何使用坐标连接 pandas 中的两个数据框
How to join two dataframes in pandas using coordinates
我有两个坐标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]
没有示例,我不会写出准确的代码,但会逐行提出改进建议。一般的想法是 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
将其应用于数据帧中的每一行来改进。
最后,使用 argmin
或 idxmin
应该比:
更快
archivo2[archivo2['Distancia']==archivo2['Distancia'].min()]
将以上所有内容放在一起,您应该已经看到了相当大的改进!
我有两个坐标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]
没有示例,我不会写出准确的代码,但会逐行提出改进建议。一般的想法是 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
将其应用于数据帧中的每一行来改进。
最后,使用 argmin
或 idxmin
应该比:
archivo2[archivo2['Distancia']==archivo2['Distancia'].min()]
将以上所有内容放在一起,您应该已经看到了相当大的改进!