zwrankin / porygon

A Python package to manipulate and visualize geospatial data
MIT License
2 stars 0 forks source link

Support Multi-indexed PorygonDataFrames #17

Open zwrankin opened 4 years ago

zwrankin commented 4 years ago

If the aggfunc used in PorygonDataFrame initialization would create a MultiIndexed dataframe, it will error. GeoDataFrames do indeed support multi-indexing.

Reproducible error:

df = pd.DataFrame({
    'latitude': [40, 41],
    'longitude': [-91, -90],
    'var': [1, 2]
})
h3df = PorygonDataFrame().from_h3(df, aggfunc={'var': 'mean'}).  # works
h3df = PorygonDataFrame().from_h3(df, aggfunc={'var': ['mean', 'sum']})

Raises the following error:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-35-f701c97545d8> in <module>
      4     'var': [1, 2]
      5 })
----> 6 h3df = PorygonDataFrame().from_h3(df, aggfunc={'var': ['mean', 'sum']})
      7 h3df

~/github/porygon/porygon/porygondataframe.py in from_h3(self, df, h3_level, aggfunc)
     39 
     40     def from_h3(self, df, h3_level=8, aggfunc=np.sum):
---> 41         return _df_to_h3(df, h3_level=h3_level, aggfunc=aggfunc)
     42 
     43     def from_boundaries(self, df: pd.DataFrame, boundaries: GeoDataFrame, aggfunc=np.sum):

~/github/porygon/porygon/porygondataframe.py in _df_to_h3(df, h3_level, aggfunc)
    227     df['geometry'] = df.id.apply(h3_to_polygon)
    228 
--> 229     return PorygonDataFrame(df.set_index('id'))
    230 
    231 

~/github/porygon/porygon/porygondataframe.py in __init__(self, *args, **kwargs)
     24 
     25     def __init__(self, *args, **kwargs):
---> 26         super().__init__(*args, **kwargs)
     27         if len(self) > 0:  # if initialized from a constructor, not PorygonDataFrame()
     28             centroids = self.centroid

~/miniconda3/envs/porygon/lib/python3.7/site-packages/geopandas/geodataframe.py in __init__(self, *args, **kwargs)
     75             index = self.index
     76             try:
---> 77                 self["geometry"] = _ensure_geometry(self["geometry"].values)
     78             except TypeError:
     79                 pass

~/miniconda3/envs/porygon/lib/python3.7/site-packages/geopandas/geodataframe.py in __getitem__(self, key)
    574         GeoDataFrame.
    575         """
--> 576         result = super(GeoDataFrame, self).__getitem__(key)
    577         geo_col = self._geometry_column_name
    578         if isinstance(key, str) and key == geo_col:

~/miniconda3/envs/porygon/lib/python3.7/site-packages/pandas/core/frame.py in __getitem__(self, key)
   2773             if self.columns.is_unique and key in self.columns:
   2774                 if self.columns.nlevels > 1:
-> 2775                     return self._getitem_multilevel(key)
   2776                 return self._get_item_cache(key)
   2777 

~/miniconda3/envs/porygon/lib/python3.7/site-packages/pandas/core/frame.py in _getitem_multilevel(self, key)
   2852             result_columns = maybe_droplevels(new_columns, key)
   2853             if self._is_mixed_type:
-> 2854                 result = self.reindex(columns=new_columns)
   2855                 result.columns = result_columns
   2856             else:

~/miniconda3/envs/porygon/lib/python3.7/site-packages/pandas/util/_decorators.py in wrapper(*args, **kwargs)
    225         @wraps(func)
    226         def wrapper(*args, **kwargs) -> Callable[..., Any]:
--> 227             return func(*args, **kwargs)
    228 
    229         kind = inspect.Parameter.POSITIONAL_OR_KEYWORD

~/miniconda3/envs/porygon/lib/python3.7/site-packages/pandas/core/frame.py in reindex(self, *args, **kwargs)
   3854         kwargs.pop("axis", None)
   3855         kwargs.pop("labels", None)
-> 3856         return self._ensure_type(super().reindex(**kwargs))
   3857 
   3858     def drop(

~/miniconda3/envs/porygon/lib/python3.7/site-packages/pandas/core/base.py in _ensure_type(self, obj)
     91         Used by type checkers.
     92         """
---> 93         assert isinstance(obj, type(self)), type(obj)
     94         return obj
     95 

AssertionError: <class 'geopandas.geodataframe.GeoDataFrame'>