Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLN/DEPR: remove Block._holder, deprecated Block.is_categorical #40571

Merged
merged 3 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 16 additions & 26 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Union,
cast,
)
import warnings

import numpy as np

Expand Down Expand Up @@ -191,16 +192,6 @@ def __init__(self, values, placement: BlockPlacement, ndim: int):
self._mgr_locs = placement
self.values = values

@property
def _holder(self):
"""
The array-like that can hold the underlying values.

None for 'Block', overridden by subclasses that don't
use an ndarray.
"""
return None

@final
@property
def _consolidate_key(self):
Expand All @@ -227,7 +218,13 @@ def _can_hold_na(self) -> bool:
@final
@property
def is_categorical(self) -> bool:
return self._holder is Categorical
warnings.warn(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there something that actually tests this warning?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, its a DeprecationWarning, just for eg pyarrow

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right but shouldn't we assert it

"Block.is_categorical is deprecated and will be removed in a "
"future version. Use isinstance(block.values, Categorical) "
"instead. See https://github.com/pandas-dev/pandas/issues/40226",
DeprecationWarning,
)
return isinstance(self.values, Categorical)

@final
def external_values(self):
Expand Down Expand Up @@ -797,8 +794,10 @@ def _replace_list(
"""
See BlockManager._replace_list docstring.
"""
values = self.values

# TODO: dont special-case Categorical
if self.is_categorical and len(algos.unique(dest_list)) == 1:
if isinstance(values, Categorical) and len(algos.unique(dest_list)) == 1:
# We likely got here by tiling value inside NDFrame.replace,
# so un-tile here
return self.replace(src_list, dest_list[0], inplace, regex)
Expand All @@ -813,17 +812,17 @@ def _replace_list(

src_len = len(pairs) - 1

if self.is_object:
if values.dtype == _dtype_obj:
# Calculate the mask once, prior to the call of comp
# in order to avoid repeating the same computations
mask = ~isna(self.values)
mask = ~isna(values)
masks = [
compare_or_regex_search(self.values, s[0], regex=regex, mask=mask)
compare_or_regex_search(values, s[0], regex=regex, mask=mask)
for s in pairs
]
else:
# GH#38086 faster if we know we dont need to check for regex
masks = [missing.mask_missing(self.values, s[0]) for s in pairs]
masks = [missing.mask_missing(values, s[0]) for s in pairs]

# error: Argument 1 to "extract_bool_array" has incompatible type
# "Union[ExtensionArray, ndarray, bool]"; expected "Union[ExtensionArray,
Expand Down Expand Up @@ -1504,11 +1503,6 @@ def putmask(self, mask, new) -> List[Block]:
new_values[mask] = new
return [self.make_block(values=new_values)]

@property
def _holder(self):
# For extension blocks, the holder is values-dependent.
return type(self.values)

@property
def is_view(self) -> bool:
"""Extension arrays are never treated as views."""
Expand Down Expand Up @@ -1714,7 +1708,7 @@ def where(self, other, cond, errors="raise") -> List[Block]:
# NotImplementedError for class not implementing `__setitem__`
# TypeError for SparseArray, which implements just to raise
# a TypeError
result = self._holder._from_sequence(
result = type(self.values)._from_sequence(
np.where(cond, self.values, other), dtype=dtype
)

Expand Down Expand Up @@ -1904,10 +1898,6 @@ class DatetimeLikeBlockMixin(NDArrayBackedExtensionBlock):
def array_values(self):
return ensure_wrapped_if_datetimelike(self.values)

@property
def _holder(self):
return type(self.array_values())


class DatetimeBlock(DatetimeLikeBlockMixin):
__slots__ = ()
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/internals/concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import pandas.core.algorithms as algos
from pandas.core.arrays import (
Categorical,
DatetimeArray,
ExtensionArray,
)
Expand Down Expand Up @@ -367,7 +368,7 @@ def get_reindexed_values(self, empty_dtype: DtypeObj, upcasted_na) -> ArrayLike:
# preserve these for validation in concat_compat
return self.block.values

if self.block.is_bool and not self.block.is_categorical:
if self.block.is_bool and not isinstance(self.block.values, Categorical):
# External code requested filling/upcasting, bool values must
# be upcasted to object to avoid being upcasted to numeric.
values = self.block.astype(np.object_).values
Expand Down
21 changes: 1 addition & 20 deletions pandas/tests/internals/test_internals.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@
)
import pandas._testing as tm
import pandas.core.algorithms as algos
from pandas.core.arrays import (
DatetimeArray,
SparseArray,
TimedeltaArray,
)
from pandas.core.arrays import SparseArray
from pandas.core.internals import (
BlockManager,
SingleBlockManager,
Expand Down Expand Up @@ -1302,21 +1298,6 @@ def test_should_store_categorical(self):
assert not blk.should_store(np.asarray(cat))


@pytest.mark.parametrize(
"typestr, holder",
[
("category", Categorical),
("M8[ns]", DatetimeArray),
("M8[ns, US/Central]", DatetimeArray),
("m8[ns]", TimedeltaArray),
("sparse", SparseArray),
],
)
def test_holder(typestr, holder, block_maker):
blk = create_block(typestr, [1], maker=block_maker)
assert blk._holder is holder


def test_validate_ndim(block_maker):
values = np.array([1.0, 2.0])
placement = slice(2)
Expand Down