PANDAS-GEOPANDAS:shapefile 中点的定位
PANDAS-GEOPANDAS: Localization of points in a shapefile
使用 pandas 和 geopandas,我想定义一个应用于数据帧每一行的函数,其操作如下:
输入:带坐标的列
输出:点落入的区域。
我试过这个,但是需要很长时间。
def zone_assign(point,zones,codes):
try:
zone_label=zones[zones['geometry'].contains(point)][codes].values[0]
except:
zone_label=np.NaN
return(zone_label)
其中:
point 是包含地理坐标的行的单元格;
zones 是用 geopandas 导入的 shapefile;
codes 是 shapefile 的列,其中包含要分配给该点的标签。
部分答案,摘自我之前的另一个答案
您的情况看起来像是 spatial joins
有用的典型案例。空间连接的思想是使用地理坐标而不是使用属性来合并数据。
geopandas
中的三种可能性:
intersects
within
contains
您似乎想要 contains
,可以使用以下语法实现:
geopandas.sjoin(polygons, points, how="inner", op='contains')
注意:您需要安装 rtree
才能执行此类操作。如果需要安装这个依赖,使用pip
或者conda
安装
例子
举个例子,让我们随机抽取一个相关城市和地块国家的样本。两个示例数据集是
import geopandas
import matplotlib.pyplot as plt
world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
cities = geopandas.read_file(geopandas.datasets.get_path('naturalearth_cities'))
cities = cities.sample(n=50, random_state=1)
world.head(2)
pop_est continent name iso_a3 gdp_md_est geometry
0 920938 Oceania Fiji FJI 8374.0 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 53950935 Africa Tanzania TZA 150600.0 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
cities.head(3)
name geometry
196 Bogota POINT (-74.08529 4.59837)
95 Tbilisi POINT (44.78885 41.72696)
173 Seoul POINT (126.99779 37.56829)
world
是一个全球数据集,cities
是一个子集。
两个数据集需要在同一个投影系统中。如果不是,请在合并前使用 .to_crs
。
data_merged = geopandas.sjoin(countries, cities, how="inner", op='contains')
最后,为了查看结果让我们做一张地图
f, ax = plt.subplots(1, figsize=(20,10))
data_merged.plot(axes=ax)
countries.plot(axes=ax, alpha=0.25, linewidth=0.1)
plt.show()
底层数据集将我们需要的信息合并在一起
data_merged.head(2)
pop_est continent name_left iso_a3 gdp_md_est geometry index_right name_right
7 6909701 Oceania Papua New Guinea PNG 28020.0 MULTIPOLYGON (((141.00021 -2.60015, 142.73525 ... 59 Port Moresby
9 44293293 South America Argentina ARG 879400.0 MULTIPOLYGON (((-68.63401 -52.63637, -68.25000... 182 Buenos Aires
在这里,我使用了 inner
连接方法,但这是一个您可以更改的参数,例如,如果您想保留所有点,包括那些不在多边形内的点。
使用 pandas 和 geopandas,我想定义一个应用于数据帧每一行的函数,其操作如下: 输入:带坐标的列 输出:点落入的区域。
我试过这个,但是需要很长时间。
def zone_assign(point,zones,codes):
try:
zone_label=zones[zones['geometry'].contains(point)][codes].values[0]
except:
zone_label=np.NaN
return(zone_label)
其中: point 是包含地理坐标的行的单元格; zones 是用 geopandas 导入的 shapefile; codes 是 shapefile 的列,其中包含要分配给该点的标签。
部分答案,摘自我之前的另一个答案
您的情况看起来像是 spatial joins
有用的典型案例。空间连接的思想是使用地理坐标而不是使用属性来合并数据。
geopandas
中的三种可能性:
intersects
within
contains
您似乎想要 contains
,可以使用以下语法实现:
geopandas.sjoin(polygons, points, how="inner", op='contains')
注意:您需要安装 rtree
才能执行此类操作。如果需要安装这个依赖,使用pip
或者conda
安装
例子
举个例子,让我们随机抽取一个相关城市和地块国家的样本。两个示例数据集是
import geopandas
import matplotlib.pyplot as plt
world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
cities = geopandas.read_file(geopandas.datasets.get_path('naturalearth_cities'))
cities = cities.sample(n=50, random_state=1)
world.head(2)
pop_est continent name iso_a3 gdp_md_est geometry
0 920938 Oceania Fiji FJI 8374.0 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 53950935 Africa Tanzania TZA 150600.0 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
cities.head(3)
name geometry
196 Bogota POINT (-74.08529 4.59837)
95 Tbilisi POINT (44.78885 41.72696)
173 Seoul POINT (126.99779 37.56829)
world
是一个全球数据集,cities
是一个子集。
两个数据集需要在同一个投影系统中。如果不是,请在合并前使用 .to_crs
。
data_merged = geopandas.sjoin(countries, cities, how="inner", op='contains')
最后,为了查看结果让我们做一张地图
f, ax = plt.subplots(1, figsize=(20,10))
data_merged.plot(axes=ax)
countries.plot(axes=ax, alpha=0.25, linewidth=0.1)
plt.show()
data_merged.head(2)
pop_est continent name_left iso_a3 gdp_md_est geometry index_right name_right
7 6909701 Oceania Papua New Guinea PNG 28020.0 MULTIPOLYGON (((141.00021 -2.60015, 142.73525 ... 59 Port Moresby
9 44293293 South America Argentina ARG 879400.0 MULTIPOLYGON (((-68.63401 -52.63637, -68.25000... 182 Buenos Aires
在这里,我使用了 inner
连接方法,但这是一个您可以更改的参数,例如,如果您想保留所有点,包括那些不在多边形内的点。