From 79f1801f27c54b91e8901e5f6f9e7926eea17050 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 23 Mar 2021 17:08:02 +0100 Subject: [PATCH] COMPAT: add back dummy CategoricalBlock class (#40582) --- pandas/core/internals/__init__.py | 5 ++++- pandas/core/internals/blocks.py | 11 ++++++++--- pandas/core/internals/managers.py | 8 ++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pandas/core/internals/__init__.py b/pandas/core/internals/__init__.py index 18e584575bc97..f0018928255e6 100644 --- a/pandas/core/internals/__init__.py +++ b/pandas/core/internals/__init__.py @@ -26,6 +26,7 @@ __all__ = [ "Block", + "CategoricalBlock", "NumericBlock", "DatetimeBlock", "DatetimeTZBlock", @@ -56,6 +57,8 @@ def __getattr__(name: str): DeprecationWarning, stacklevel=2, ) - return ExtensionBlock + from pandas.core.internals.blocks import CategoricalBlock + + return CategoricalBlock raise AttributeError(f"module 'pandas.core.internals' has no attribute '{name}'") diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index c13eb3f109354..0c92a2f8515fd 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1244,7 +1244,7 @@ def take_nd( Take values according to indexer and return them as a block.bb """ - # algos.take_nd dispatches for DatetimeTZBlock + # algos.take_nd dispatches for DatetimeTZBlock, CategoricalBlock # so need to preserve types # sparse is treated like an ndarray, but needs .get_values() shaping @@ -1443,7 +1443,7 @@ class ExtensionBlock(Block): Notes ----- This holds all 3rd-party extension array types. It's also the immediate - parent class for our internal extension types' blocks. + parent class for our internal extension types' blocks, CategoricalBlock. ExtensionArrays are limited to 1-D. """ @@ -2017,6 +2017,11 @@ def _can_hold_element(self, element: Any) -> bool: return True +class CategoricalBlock(ExtensionBlock): + # this Block type is kept for backwards-compatibility + __slots__ = () + + # ----------------------------------------------------------------- # Constructor Helpers @@ -2078,7 +2083,7 @@ def get_block_type(values, dtype: Optional[Dtype] = None): # Need this first(ish) so that Sparse[datetime] is sparse cls = ExtensionBlock elif isinstance(dtype, CategoricalDtype): - cls = ExtensionBlock + cls = CategoricalBlock elif vtype is Timestamp: cls = DatetimeTZBlock elif vtype is Interval or vtype is Period: diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index ef2925874c0ac..759500827f344 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -67,6 +67,7 @@ ) from pandas.core.internals.blocks import ( Block, + CategoricalBlock, DatetimeTZBlock, ExtensionBlock, ObjectValuesExtensionBlock, @@ -1860,6 +1861,13 @@ def _form_blocks( object_blocks = _simple_blockify(items_dict["ObjectBlock"], np.object_) blocks.extend(object_blocks) + if len(items_dict["CategoricalBlock"]) > 0: + cat_blocks = [ + new_block(array, klass=CategoricalBlock, placement=i, ndim=2) + for i, array in items_dict["CategoricalBlock"] + ] + blocks.extend(cat_blocks) + if len(items_dict["ExtensionBlock"]): external_blocks = [ new_block(array, klass=ExtensionBlock, placement=i, ndim=2)