【问题标题】:Selecting rows in geopandas or pandas based on latitude/longitude and radius根据纬度/经度和半径选择 geopandas 或 pandas 中的行
【发布时间】:2019-10-24 20:14:11
【问题描述】:

我有一个数据框 (pd),其中每一行包含一组度量值,以及 latitudelongitude 值。如果需要,我可以将它们转换为 geopandas 点。

从这个数据框中,我想只选择从新的给定纬度/经度落在某个(比如说 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.4long = -79.5

【问题讨论】:

  • 计算从给定纬度/经度到数据帧中每个点的距离,然后在数据帧上使用布尔索引。如果您有示例数据,代码将可用。

标签: python database pandas gis geopandas


【解决方案1】:

这是一个工作代码示例。首先做一个函数来计算你的距离。我实现了一个简单的距离计算,但我会推荐你​​觉得最有用的那个。接下来,您可以将 DataFrame 子集化到您想要的距离内。

#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]

【讨论】:

  • 这是个好主意,如果没有更好的解决方案,我会使用类似的方法。我正在寻找类似基于位置的查询(例如 PostGIS 中的 ST_DistanceSphere
【解决方案2】:

您可以使用以下算法:

  1. 从输入数据(pd 数据框)创建一个地理数据框(gdfdata

  2. 使用中心点创建另一个地理数据框 (gdfsel) 以供选择

  3. 围绕中心点创建一个缓冲区(从gdfsel 生成gdfselbuff)以供选择

  4. 使用 geopandas 的 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

【讨论】:

    【解决方案3】:

    在 Sharder 的解决方案之上,我发现应用过滤功能很方便。它似乎也执行得更快

    def filter(row,lat2,lon2,max):
        if getDist(row['lat'],row['lon'],lat2,lon2) < max:
            return True
        else:
            return False
    
    df[df.apply(filter, args = (newlat,newlon,600), axis=1)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多