Ваша ситуация выглядит как типичный случай, когда spatial joins
полезны. Идея пространственных объединений заключается в объединении данных с использованием географических c координат вместо использования атрибутов.
Три возможности в geopandas
:
intersects
within
contains
Похоже, вы хотите within
, что возможно с использованием следующего синтаксиса:
geopandas.sjoin(points, polygons, how="inner", op='within')
Примечание. Для выполнения таких операций необходимо установить 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'))
countries = world[world['continent'] == "Europe"].rename(columns={'name':'country'})
countries.head(2)
pop_est continent country iso_a3 gdp_md_est geometry
18 142257519 Europe Russia RUS 3745000.0 MULTIPOLYGON (((178.725 71.099, 180.000 71.516...
21 5320045 Europe Norway -99 364700.0 MULTIPOLYGON (((15.143 79.674, 15.523 80.016, ...
cities.head(2)
name geometry
0 Vatican City POINT (12.45339 41.90328)
1 San Marino POINT (12.44177 43.93610)
cities
- это набор данных по всему миру, а countries
- это набор данных по всей Европе.
Оба набора данных должны находиться в одной проекционной системе. Если нет, используйте .to_crs
перед объединением.
data_merged = geopandas.sjoin(cities, countries, how="inner", op='within')
Наконец, чтобы увидеть результат, давайте создадим карту
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(5)
name geometry index_right pop_est continent country iso_a3 gdp_md_est
0 Vatican City POINT (12.45339 41.90328) 141 62137802 Europe Italy ITA 2221000.0
1 San Marino POINT (12.44177 43.93610) 141 62137802 Europe Italy ITA 2221000.0
192 Rome POINT (12.48131 41.89790) 141 62137802 Europe Italy ITA 2221000.0
2 Vaduz POINT (9.51667 47.13372) 114 8754413 Europe Austria AUT 416600.0
184 Vienna POINT (16.36469 48.20196) 114 8754413 Europe Austria AUT 416600.0
Здесь я использовал inner
метод соединения, но это параметр, который вы можете изменить, если, например, вы хотите сохранить все точки, в том числе не в пределах многоугольника.