j'ai une latitude et la longitude stockée dans une trame de données de panda (df
) avec des points de remplissage comme NaN
pour stop_id, stoplat, stoplon
, et dans une autre trame de données areadf
, qui contient plus de lats/lons et arbitraire id; c'est l'information qui doit être remplie en df
. J'essaie de connecter les deux pour que les colonnes d'arrêt dans df
contiennent des informations sur l'arrêt le plus proche de ce point lat/lon, ou laissez NaN
s'il n'y a pas d'arrêt dans un rayon R du point.Accélérer un imbriquée pour une boucle à travers deux Pandas DataFrames
En ce moment, mon code est le suivant, mais il faut un temps très long (> 40 minutes pour ce que je suis en train de faire, avant de changer de zone en df et d'utiliser des cela fera?) car il y a des milliers de points de latitude/longitude et d'arrêts pour chaque ensemble de données, ce qui est un problème car je dois l'exécuter sur plusieurs fichiers. Je cherche des suggestions pour le faire fonctionner plus vite. J'ai déjà apporté quelques améliorations mineures (par exemple, passer à un dataframe, utiliser des itertuples au lieu de iterrows, définir des lats et des lons en dehors de la boucle pour éviter d'avoir à le récupérer depuis df) mais je n'ai plus d'idée l'accélérer. getDistance
utilise la formule de Haversine telle que définie pour obtenir la distance entre le signe d'arrêt et le point lat, lon donné.
import pandas as pd
from math import cos, asin, sqrt
R=5
lats = df['lat']
lons = df['lon']
for stop in areadf.itertuples():
for index in df.index:
if getDistance(lats[index],lons[index],
stop[1],stop[2]) < R:
df.at[index,'stop_id'] = stop[0] # id
df.at[index,'stoplat'] = stop[1] # lat
df.at[index,'stoplon'] = stop[2] # lon
def getDistance(lat1,lon1,lat2,lon2):
p = 0.017453292519943295 #Pi/180
a = (0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) *
cos(lat2 * p) * (1 - cos((lon2 - lon1) * p))/2)
return 12742 * asin(sqrt(a)) * 100
données de l'échantillon:
df
lat lon stop_id stoplat stoplon
43.657676 -79.380146 NaN NaN NaN
43.694324 -79.334555 NaN NaN NaN
areadf
stop_id stoplat stoplon
0 43.657675 -79.380145
1 45.435143 -90.543253
Souhaité:
df
lat lon stop_id stoplat stoplon
43.657676 -79.380146 0 43.657675 -79.380145
43.694324 -79.334555 NaN NaN NaN
vous pouvez utiliser pypy au lieu de cython, pypy à c compile pour accélérer les boucles en python –
1. Ne pas itérer sur les dataframes comme ça, tirer parti des pandas géants 2. utiliser la distance euclidienne comme une première passe, Soustrayez vos données en grilles lat/lon, où rien dans la grille x et ses 8 cellules environnantes ne se trouve à l'intérieur de R de quoi que ce soit dans la grille y, et courez sur les arrêts de sous-ensembles vs points . – jeremycg
@jeremycg Avez-vous des fonctions que vous suggérez de mieux prendre en compte pour profiter des pandas? Merci pour votre réponse! – amper