# Geopandas performance appears quite slow

I'd like to confirm the performance I am observing when utilizing `distance` from a Geopandas `Series`.

### Problem

Time to complete operations appears to be far greater than comparable operation in PostGIS. I would like to understand if this is known and, if so, if there are suggestions as to methods for making Geopandas more performant, particular regarding geo operations like buffering.

### Goal

Given a set of geometries, I would like to calculate some aggregate (e.g. `sum()`) for each geometry plus those that fall within a given distance of the reference geometry.

### Example

Given a set of geometries, I would like to calculate a quarter mile buffer (402 meters) around them and gather the sum the attribute `du` (dwelling units).

### Current Strategy

Current method, utilizing solely the centroids in an attempt to be performant:

``````# precompute the centroids
centroids = df['wkb_geometry'].centroid

def test_measure(row):
center = row['wkb_geometry'].centroid
return df.loc[centroids.distance(center) < 402, 'du'].sum()

df.apply(lambda row: test_measure(row), axis=1)
``````

Precomputing centroid and then using distance does appear to introduce some efficiencies compared to buffering and using `within` operation. Cost, regardless of methodology, grows at rate `n^2` due to the fact that `test_measure` runs `n` times where `n` is the row count and must be run once for each of the `n` rows.

Times:

• 100 rows: 0.17s
• 1000 rows: 11.11s

### Prior strategy

Prior, with buffering and `within` it took about:

• 100 rows: 1s
• 1000 rows: 100s

Prior method, not using centroids:

``````def test_measure(row):
buffer_shape = row['wkb_geometry'].buffer(500)
return df.loc[df['wkb_geometry'].within(buffer_shape), 'du'].sum()
``````

### Thoughts

Were I to perform a similar operation (using `st_dwithin`) in PostGIS, I would be able to run the operation in the following times.

Times:

• 100 rows: not run
• 1000 rows: not run
• 24000 rows: 75s

For reference, here is an example of that sort of SQL query:

``````CREATE OR REPLACE FUNCTION agg_within_dist(
in_id int,
in_geometry geometry,
OUT id int,
OUT du float)
AS
\$\$
SELECT
\$1 AS geography_id,
SUM(CAST(ref.du AS float)) AS du
FROM s1.s1_scenario_final AS REF WHERE st_dwithin(\$2, ref.wkb_geometry, 402);
\$\$
COST 10000
LANGUAGE SQL STABLE strict;

SELECT (f).*
FROM (
SELECT agg_within_dist(geography_id, wkb_geometry) AS f
FROM scenario
) s
``````