tlamadon / pytwoway

Two way models in python
MIT License
24 stars 7 forks source link

AttributeError: 'BipartiteLong' object has no attribute 'columns_req' #50

Closed MartinHaus1993 closed 1 year ago

MartinHaus1993 commented 1 year ago

Hi all,

Thanks for the great package! I have updated some of my system today and it appears this has broken my pytwoway configuration.

I am running python 3.10.8, pytwoway 0.3.21, and bipartitepandas 1.1.9 on OSX (all installed via pip). When running the FE notebook ( https://tlamadon.github.io/pytwoway/notebooks/fe_example.html ), I get the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
[/var/folders/pk/jy78bg3s5p12wkbr0244zw3h0000gn/T/ipykernel_54928/4116612111.py](https://untitled+.vscode-resource.vscode-cdn.net/var/folders/pk/jy78bg3s5p12wkbr0244zw3h0000gn/T/ipykernel_54928/4116612111.py) in ?()
     35 sim_data = bpd.SimBipartite(sim_params).simulate()
     36 
     37 
     38 # Convert into BipartitePandas DataFrame
---> 39 bdf = bpd.BipartiteDataFrame(sim_data)
     40 # Clean and collapse
     41 bdf = bdf.clean(clean_params)

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitedataframe.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitedataframe.py) in ?(cls, i, j, j1, j2, y, y1, y2, t, t1, t2, t11, t12, t21, t22, g, g1, g2, w, w1, w2, m, custom_categorical_dict, custom_dtype_dict, custom_how_collapse_dict, custom_long_es_split_dict, **kwargs)
     53         Return dataframe (source: https:[//](https://github.com/tlamadon/pytwoway/issues/new)stackoverflow.com[/](https://untitled+.vscode-resource.vscode-cdn.net/)a[/](https://untitled+.vscode-resource.vscode-cdn.net/)2491881[/](https://untitled+.vscode-resource.vscode-cdn.net/)17333120).
     54         '''
     55         if isinstance(i, DataFrame):
     56             # If user didn't split arguments, do it for them
---> 57             return BipartiteDataFrame(**i, custom_categorical_dict=custom_categorical_dict, custom_dtype_dict=custom_dtype_dict, custom_how_collapse_dict=custom_how_collapse_dict, custom_long_es_split_dict=custom_long_es_split_dict, **kwargs)
     58         # Update custom dictionaries to be dictionaries instead of None (source: https://stackoverflow.com/a/54781084/17333120)
     59         if custom_categorical_dict is None:
     60             custom_categorical_dict = {}

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitedataframe.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitedataframe.py) in ?(cls, i, j, j1, j2, y, y1, y2, t, t1, t2, t11, t12, t21, t22, g, g1, g2, w, w1, w2, m, custom_categorical_dict, custom_dtype_dict, custom_how_collapse_dict, custom_long_es_split_dict, **kwargs)
    346                 col_reference = bpd.util.to_list(new_cols_reference_dict[new_col_name])
    347                 if len(col_reference) == 1:
    348                     # Constructed col_references are forced to be lists, if it's length one then just extract the single value from the list
    349                     col_reference = col_reference[0]
--> 350                 df = df.add_column(new_col_name, new_col_data, col_reference=col_reference, is_categorical=custom_categorical_dict[new_col_name], dtype=custom_dtype_dict[new_col_name], how_collapse=custom_how_collapse_dict[new_col_name], long_es_split=custom_long_es_split_dict[new_col_name], copy=False)
    351 
    352         return df

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py) in ?(self, col_name, col_data, col_reference, is_categorical, dtype, how_collapse, long_es_split, copy)
    493             for i, subcol in enumerate(to_list(frame.col_reference_dict[col_name])):
    494                 frame.loc[:, subcol] = col_data_lst[i]
    495 
    496         # Sort columns
--> 497         frame = frame.sort_cols(copy=False)
    498 
    499         return frame

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py) in ?(self, copy)
   1355             frame = self
   1356 
   1357         # Sort columns
   1358         sorted_cols = bpd.util._sort_cols(frame.columns)
-> 1359         frame = frame.reindex(sorted_cols, axis=1, copy=False)
   1360 
   1361         return frame

[/usr/local/lib/python3.10/site-packages/pandas/core/frame.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/frame.py) in ?(self, labels, index, columns, axis, method, copy, level, fill_value, limit, tolerance)
   5140         fill_value: Scalar | None = np.nan,
   5141         limit: int | None = None,
   5142         tolerance=None,
   5143     ) -> DataFrame:
-> 5144         return super().reindex(
   5145             labels=labels,
   5146             index=index,
   5147             columns=columns,

[/usr/local/lib/python3.10/site-packages/pandas/core/generic.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/generic.py) in ?(self, labels, index, columns, axis, method, copy, level, fill_value, limit, tolerance)
   5517         if self._needs_reindex_multi(axes, method, level):
   5518             return self._reindex_multi(axes, copy, fill_value)
   5519 
   5520         # perform the reindex on the axes
-> 5521         return self._reindex_axes(
   5522             axes, level, limit, tolerance, method, fill_value, copy
   5523         ).__finalize__(self, method="reindex")

[/usr/local/lib/python3.10/site-packages/pandas/core/generic.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/generic.py) in ?(self, axes, level, limit, tolerance, method, fill_value, copy)
   5545                 labels, level=level, limit=limit, tolerance=tolerance, method=method
   5546             )
   5547 
   5548             axis = self._get_axis_number(a)
-> 5549             obj = obj._reindex_with_indexers(
   5550                 {axis: [new_index, indexer]},
   5551                 fill_value=fill_value,
   5552                 copy=copy,

[/usr/local/lib/python3.10/site-packages/pandas/core/generic.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/generic.py) in ?(self, reindexers, fill_value, copy, allow_dups)
   5613             new_data = new_data.copy(deep=copy)
   5614         elif using_copy_on_write() and new_data is self._mgr:
   5615             new_data = new_data.copy(deep=False)
   5616 
-> 5617         return self._constructor_from_mgr(new_data, axes=new_data.axes).__finalize__(
   5618             self
   5619         )

[/usr/local/lib/python3.10/site-packages/pandas/core/frame.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/frame.py) in ?(self, mgr, axes)
    645             # fastpath avoiding constructor call
    646             return df
    647         else:
    648             assert axes is mgr.axes
--> 649             return self._constructor(df, copy=False)

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitelong.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitelong.py) in ?(self, col_reference_dict, col_collapse_dict, *args, **kwargs)
     25             col_collapse_dict = {}
     26         col_reference_dict = bpd.util.update_dict({'t': 't'}, col_reference_dict)
     27         col_collapse_dict = bpd.util.update_dict({'m': 'sum'}, col_collapse_dict)
     28         # Initialize DataFrame
---> 29         super().__init__(*args, col_reference_dict=col_reference_dict, col_collapse_dict=col_collapse_dict, **kwargs)
     30 
     31         # self.log('BipartiteLong object initialized', level='info')

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitelongbase.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitelongbase.py) in ?(self, col_reference_dict, *args, **kwargs)
     21         if col_reference_dict is None:
     22             col_reference_dict = {}
     23         col_reference_dict = bpd.util.update_dict({'j': 'j', 'y': 'y', 'g': 'g', 'w': 'w'}, col_reference_dict)
     24         # Initialize DataFrame
---> 25         super().__init__(*args, col_reference_dict=col_reference_dict, **kwargs)
     26 
     27         # self.log('BipartiteLongBase object initialized', level='info')

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py) in ?(self, columns_req, columns_opt, columns_contig, col_reference_dict, col_dtype_dict, col_collapse_dict, col_long_es_dict, track_id_changes, log, *args, **kwargs)
    185             col_long_es_dict = {}
    186 
    187         if len(args) > 0 and isinstance(args[0], BipartiteBase):
    188             # Note that isinstance works for subclasses
--> 189             self._set_attributes(args[0], no_dict=False, track_id_changes=track_id_changes)
    190             # Update class attributes from the previous dataframe with parameter inputs
    191             self.columns_req = ['i', 'j', 'y'] + [column_req for column_req in self.columns_req if column_req not in ['i', 'j', 'y']]
    192             self.columns_opt = ['t', 'g', 'w', 'm'] + [column_opt for column_opt in self.columns_opt if column_opt not in ['t', 'g', 'w', 'm']]

[/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/bipartitepandas/bipartitebase.py) in ?(self, frame, no_dict, track_id_changes)
    714             track_id_changes (bool): if True, create dictionary of Pandas dataframes linking original categorical id values to updated contiguous id values
    715         '''
    716         # Dictionaries
    717         if not no_dict:
--> 718             self.columns_req = frame.columns_req.copy()
    719             self.columns_opt = frame.columns_opt.copy()
    720             self.col_reference_dict = frame.col_reference_dict.copy()
    721         # Required, even if no_dict

[/usr/local/lib/python3.10/site-packages/pandas/core/generic.py](https://untitled+.vscode-resource.vscode-cdn.net/usr/local/lib/python3.10/site-packages/pandas/core/generic.py) in ?(self, name)
   6200             and name not in self._accessors
   6201             and self._info_axis._can_hold_identifiers_and_holds_name(name)
   6202         ):
   6203             return self[name]
-> 6204         return object.__getattribute__(self, name)

AttributeError: 'BipartiteLong' object has no attribute 'columns_req'

When using my own dataset, the same error appears as soon as I try to do something with the BipartiteDataFrame (such as printing it or cleaning it).

I might be missing something obvious here, but any help would be highly appreciated!

Thanks!

Best, Martin

adamoppenheimer commented 1 year ago

Hi Martin,

Thanks for using the package!

I'm sorry about the issue you are having.

It looks like this may be something related to Pandas.

What version of Pandas are you using? And what happens if you try downgrading Pandas?

Best, Adam

MartinHaus1993 commented 1 year ago

Hi Adam,

Thanks for the quick response. I was using Pandas 2.1.1. Downgrading to 2.0.3 (not 2.1.0) fixed this! Thanks so much, it has saved me a lot of time.

Best, Martin