Finding features of one geodataframe that contain at least one feature from another geodataframe

I have two polygon layers. One is a parcel layer (name "parcl") and the other one is a polygon layer (named "houses"). I am trying to find all parcels that contain at least one feature from the houses dataframe. I attempted to do so through a loop as shown below:

same = np.empty((0,parcl.shape[1]))

for i in parcl.index:
  for j in houses.index:
    a = parcl.loc[i]
    b = houses.loc[j]
    if (a.contains(b))==True:
      same.append(a)

Unfortunately, I got the following error message:

---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-36-cedb059e5a3b> in <module>()
      5     a = parcl.loc[i]
      6     b = houses.loc[j]
----> 7     if (a.contains(b))==True:
      8       same.append(a)

/usr/local/lib/python3.7/dist-packages/pandas/core/generic.py in __getattr__(self, name)
   5139             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   5140                 return self[name]
-> 5141             return object.__getattribute__(self, name)
   5142 
   5143     def __setattr__(self, name: str, value) -> None:

AttributeError: 'Series' object has no attribute 'contains'

Any help would be much appreciated! :)


This is a simple case of sjoin()

  • have simulated some houses (rectangles)
  • used some UK county definitions as parcels
  • gdf_contains which is result of sjoin() are now parcels that contain at least one house
  • visualised to demonstrate it has worked (green parcels)
import geopandas as gpd
import shapely.geometry
import numpy as np
import requests


world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).loc[lambda d: d["iso_a3"].eq("GBR")]
BOXES = 25
a, b, c, d = world.total_bounds

# manufactuer some houses
gdf_houses = gpd.GeoDataFrame(
    geometry=[
        shapely.geometry.box(minx, miny, maxx, maxy)
        for minx, maxx in zip(np.linspace(a, c, BOXES), np.linspace(a, c, BOXES)[1:])
        for miny, maxy in zip(np.linspace(b, d, BOXES), np.linspace(b, d, BOXES)[1:])
    ],
    crs="epsg:4326",
).sample(35)

gdf_houses.explore()
res = requests.get(
    "https://opendata.arcgis.com/datasets/37363d379f4f40fa8c3f0d28eedfdd37_0.geojson"
)
gdf_parcl = gpd.GeoDataFrame.from_features(res.json(), crs="epsg:4326")

gdf_contains = gdf_parcl.sjoin(gdf_houses)

m = gdf_parcl.explore(color="grey")
m = gdf_contains.explore(m=m, color="green")
m = gdf_houses.explore(m=m, style_kwds=dict(fillOpacity=.9))

m

enter image description here