Skip to content

Commit 9aa9808

Browse files
authored
Implement sjoin within with contains (geopandas#575)
We switch the sides of the join and use the complementary predicate. This seems to be significantly faster in the common case.
1 parent fc1461b commit 9aa9808

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

geopandas/tools/sjoin.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,23 @@ def sjoin(left_df, right_df, op='intersects', how='inner',
3131
rsuffix : string, default 'right'
3232
Suffix to apply to overlapping column names (right GeoDataFrame).
3333
"""
34+
original_op = op
35+
original_how = how
3436
allowed_hows = ('left', 'right', 'inner')
3537
if how not in allowed_hows:
3638
raise ValueError("How keyword should be one of %s, got %s"
3739
% (allowed_hows, how))
3840

41+
if op == "within":
42+
# within implemented as the inverse of contains; swap names
43+
# This is done for efficiency reasons
44+
op = 'contains'
45+
left_df, right_df = right_df, left_df
46+
if how == 'left':
47+
how = 'right'
48+
elif how == 'right':
49+
how = 'left'
50+
3951
if left_df.crs != right_df.crs:
4052
print("Warning: CRS does not match")
4153

@@ -62,6 +74,11 @@ def sjoin(left_df, right_df, op='intersects', how='inner',
6274
left = left_df.take(left_indices)
6375
right = right_df.take(right_indices)
6476

77+
if original_op == 'within': # switch back
78+
left, right = right, left
79+
n_left, n_right = n_right, n_left
80+
how = original_how
81+
6582
if how in ('inner', 'left'):
6683
del right[right._geometry_column_name]
6784
index = left.index

0 commit comments

Comments
 (0)