mggg / maup

The geospatial toolkit for redistricting data.
https://maup.readthedocs.io/en/latest/
MIT License
67 stars 23 forks source link

AttributeError: `Polygon` object has no attribute 'index' #47

Closed gabeschoenbach closed 3 years ago

gabeschoenbach commented 3 years ago

I'm getting the above Attribute Error when trying to aggregate VAP data from blocks up to precincts in Arizona. I think I remember running into this with a different shapefile and can't remember how it was fixed, so putting this issue up here. Shapefiles can be found here.

Running the following code...

import maup
import geopandas as gpd

blocks = gpd.read_file("AZ_blocks_VAP/")
precincts = gpd.read_file("AZ_precincts_data/")

variables = ["VAP", "AMINVAP", "AMIN*VAP"]

assignment = maup.assign(blocks, precincts)
precincts[variables] = blocks[variables].groupby(assignment).sum()

gives this error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-ee818f0bf79d> in <module>
      1 variables = ["VAP", "AMINVAP", "AMIN*VAP"]
      2 
----> 3 assignment = maup.assign(blocks, precincts)
      4 precincts[variables] = blocks[variables].groupby(assignment).sum()

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/crs.py in wrapped(*args, **kwargs)
     12                 )
     13             )
---> 14         return f(*args, **kwargs)
     15 
     16     return wrapped

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/assign.py in assign(sources, targets)
     10     target that covers the most of its area.
     11     """
---> 12     assignment = assign_by_covering(sources, targets)
     13     unassigned = sources[assignment.isna()]
     14     assignments_by_area = assign_by_area(unassigned, targets)

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/assign.py in assign_by_covering(sources, targets)
     20 def assign_by_covering(sources, targets):
     21     indexed_sources = IndexedGeometries(sources)
---> 22     return indexed_sources.assign(targets)
     23 
     24 

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/indexed_geometries.py in assign(self, targets)
     40     def assign(self, targets):
     41         target_geometries = get_geometries(targets)
---> 42         groups = [
     43             self.covered_by(container).apply(lambda x: container_index)
     44             for container_index, container in progress(

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/indexed_geometries.py in <listcomp>(.0)
     41         target_geometries = get_geometries(targets)
     42         groups = [
---> 43             self.covered_by(container).apply(lambda x: container_index)
     44             for container_index, container in progress(
     45                 target_geometries.items(), len(target_geometries)

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/indexed_geometries.py in covered_by(self, container)
     29 
     30     def covered_by(self, container):
---> 31         relevant_geometries = self.query(container)
     32         prepared_container = prep(container)
     33 

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/indexed_geometries.py in query(self, geometry)
     19 
     20     def query(self, geometry):
---> 21         relevant_indices = [geom.index for geom in self.spatial_index.query(geometry)]
     22         relevant_geometries = self.geometries.loc[relevant_indices]
     23         return relevant_geometries

~/miniconda3/envs/maup/lib/python3.9/site-packages/maup/indexed_geometries.py in <listcomp>(.0)
     19 
     20     def query(self, geometry):
---> 21         relevant_indices = [geom.index for geom in self.spatial_index.query(geometry)]
     22         relevant_geometries = self.geometries.loc[relevant_indices]
     23         return relevant_geometries

AttributeError: 'Polygon' object has no attribute 'index'
[AZ_precincts_data.zip](https://github.com/mggg/maup/files/6932307/AZ_precincts_data.zip)
InnovativeInventor commented 3 years ago

I'm unable to reproduce this on linux, even after downgrading my version of maup, etc. to match your installation. Perhaps this is OS-specific? This is very strange.

declanc2021 commented 3 years ago

I am getting the same error with the RI sample data linked in the README.md. I also am using Mac and want to confirm whether or not this is an OS issue? Have any OS users at MGGG found a workaround?

InnovativeInventor commented 3 years ago

https://github.com/mggg/maup/pull/44 might have fixed the issue -- could you see if upgrading to 1.0.3 (just released) fixes the issue? I can't test it myself as I can't seem to be able to reproduce this on Linux.

declanc2021 commented 3 years ago

I upgraded maup to version 1.0.3 and reset the kernel. Unfortunately, I am still getting the same error listed above when assigning blocks to precincts.

gabeschoenbach commented 3 years ago

FYI, I am still also getting this error with the latest version of maup, using MacOS Catalina. It's rendering maup pretty unusable for me unfortunately!

InnovativeInventor commented 3 years ago

@gabeschoenbach @declanc2021 can one of you two do pip freeze so we can see what version of the dependencies of maup are installed and try to reproduce this bug.

pizzimathy commented 3 years ago

Encountered this bug while running dev MAUP on Python 3.9.0 with Shapely v.1.7.1 and GeoPandas v0.9.

InnovativeInventor commented 3 years ago

@declanc2021 this issue has been fully investigated. https://github.com/geopandas/geopandas/issues/2199

Try disabling or uninstalling PyGeos (importing maup with PyGeos enabled in GeoPandas will now throw an error and show users how to disable PyGeos while we work on a more sustainable fix).

geopandas.options.use_pygeos = False