Как проверить, что точка находится внутри заданного радиуса?
У меня есть следующий код, который занимает очень много времени для выполнения. Панды DataFrames df
а также df_plants
очень маленькие (менее 1 МБ). Интересно, есть ли способ оптимизировать этот код:
import pandas as pd
import geopy.distance
import re
def is_inside_radius(latitude, longitude, df_plants, radius):
if (latitude != None and longitude != None):
lat = float(re.sub("[a-zA-Z]", "", str(latitude)))
lon = float(re.sub("[a-zA-Z]", "", str(longitude)))
for index, row in df_plants.iterrows():
coords_1 = (lat, lon)
coords_2 = (row["latitude"], row["longitude"])
dist = geopy.distance.distance(coords_1, coords_2).km
if dist <= radius:
return 1
return 0
df["inside"] = df.apply(lambda row: is_inside_radius(row["latitude"],row["longitude"],df_plants,10), axis=1)
Я использую регулярное выражение для обработки широты и долготы в df
потому что значения содержат некоторые ошибки (символы), которые должны быть удалены.
Функция is_inside_radius
проверяет, если row[latitude]
а также row[longitude]
находятся в радиусе 10 км от любой из точек в df_plants
,
2 ответа
Вы можете попробовать это?
import pandas as pd
from geopy import distance
import re
def is_inside_radius(latitude, longitude, df_plants, radius):
if (latitude != None and longitude != None):
lat = float(re.sub("[a-zA-Z]", "", str(latitude)))
lon = float(re.sub("[a-zA-Z]", "", str(longitude)))
coords_1 = (lat, lon)
for row in df_plants.itertuples():
coords_2 = (row["latitude"], row["longitude"])
if distance.distance(coords_1, coords_2).km <= radius:
return 1
return 0
df["inside"] = df.map(
lambda row: is_inside_radius(
row["latitude"],
row["longitude"],
df_plants,
10),
axis=1)
Я сталкивался с такой проблемой раньше и вижу одну простую оптимизацию: старайтесь избегать вычислений с плавающей запятой, насколько это возможно, что вы можете сделать следующим образом:
Представить:
У вас есть круг, определенный Mx и My (координаты центра) и R (радиус).
У вас есть точка, определяемая координатами X и Y.
Если ваша точка (X,Y) даже не находится в квадрате, определенном (Mx, My) и размером 2*R, то она также не будет находиться в окружности, определенной (Mx, My) и радиусом R.
В псевдокоде:
function is_inside(X,Y,Mx,My,R):
if (abs(Mx-X) >= R) OR (abs(My-Y) >= R)
then return false
else:
// and only here you perform the floating point calculation