Выбор строк в геопандах или пандах на основе широты / долготы и радиуса - PullRequest
0 голосов
/ 24 октября 2019

У меня есть фрейм данных (pd), где каждая строка содержит набор мер, а также значения latitude и longitude. При необходимости я могу преобразовать их в точки геопанды.

На этом кадре данных я бы хотел выбрать только строки, которые попадают в определенный радиус (скажем, 1 км), из нового заданного значения широты / долготы.

Есть ли мудрый способ решить эту проблему?

Вот выборка данных из df:

id .  lat  .  long  . polution . label
----------------------------------------
3  . 45.467. -79.51 .    7     . 'nice'
7  . 45.312. -79.56 .    8     . 'mediocre'

выборка lat / long будет lat = 45.4 и long = -79.5.

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Вот пример рабочего кода. Сначала сделайте функцию для расчета вашего расстояния. Я реализовал простой расчет расстояния, но я бы порекомендовал, какой из них вы считаете наиболее полезным. Затем вы можете установить подкадр данных в пределах желаемого расстояния.

#Initialize DataFrame
df=pd.DataFrame(columns=['location','lat','lon'])
df['location']=['LA','NY','LV']
df['lat']=[34.05,40.71,36.16]
df['lon']=[-118.24,-74.00,-115.14]

#New point Reno 39.53,-119.81
newlat=39.53
newlon=-119.81

#Import trig stuff from math
from math import sin, cos, sqrt, atan2,radians

#Distance function between two lat/lon
def getDist(lat1,lon1,lat2,lon2):
  R = 6373.0

  lat1 = radians(lat1)
  lon1 = radians(lon1)
  lat2 = radians(lat2)
  lon2 = radians(lon2)

  dlon = lon2 - lon1
  dlat = lat2 - lat1

  a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
  c = 2 * atan2(sqrt(a), sqrt(1 - a))

  return R * c

#Apply distance function to dataframe
df['dist']=list(map(lambda k: getDist(df.loc[k]['lat'],df.loc[k]['lon'],newlat,newlon), df.index))

#This will give all locations within radius of 600 km
df[df['dist']<600]
0 голосов
/ 25 октября 2019

Вы можете использовать следующий алгоритм:

  1. Создание геоданных (gdfdata) из входных данных (pd dataframe)

  2. Создайте еще один геоданных (gdfsel) с центральной точкой для выделения

  3. Создайте буфер вокруг центральной точки (сделайте gdfselbuff из gdfsel) для выделения

  4. Используйте метод геопанд within, чтобы найти точки внутри. Например, gdf_within = gdfdata.loc[gdfdata.geometry.within(gdfselbuff.unary_union)]

Для создания буфера вы можете использовать GeoSeries.buffer(distance, resolution)). См. Эти ссылки для справки.

http://geopandas.org/geometric_manipulations.html

https://gis.stackexchange.com/questions/253224/geopandas-buffer-using-geodataframe-while-maintaining-the-dataframe

...