如何检查点在给定半径内?

时间:2018-10-14 21:02:36

标签: python pandas geopy

我有以下代码需要很长时间才能执行。大熊猫DataFrame dfdf_plants非常小(小于1Mb)。我想知道是否有任何方法可以优化此代码:

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]是否在距df_plants中任何点10公里的半径之内。

2 个答案:

答案 0 :(得分:2)

我以前遇到过这样的问题,并且看到了一个简单的优化方法:尽可能避免浮点计算,您可以执行以下操作:
想象一下:
您有一个圆,由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

答案 1 :(得分:0)

你可以试试吗?

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)