diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 28a6f6b8c6621..e9a5191ea23a1 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -630,7 +630,6 @@ def _is_homogeneous_type(self) -> bool: if self._mgr.any_extension_types: return len({block.dtype for block in self._mgr.blocks}) == 1 else: - # Note: consolidates inplace return not self._is_mixed_type @property diff --git a/pandas/core/generic.py b/pandas/core/generic.py index f0fb34dadb257..5fe9348baade1 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -5472,8 +5472,15 @@ def _consolidate(self, inplace: bool_t = False): @property def _is_mixed_type(self) -> bool_t: - f = lambda: self._mgr.is_mixed_type - return self._protect_consolidate(f) + if len(self._mgr.blocks) == 1: + return False + + if self._mgr.any_extension_types: + # Even if they have the same dtype, we cant consolidate them, + # so we pretend this is "mixed'" + return True + + return self.dtypes.nunique() > 1 def _check_inplace_setting(self, value) -> bool_t: """ check whether we allow in-place setting with this type of value """ @@ -6253,8 +6260,7 @@ def fillna( axis = self._get_axis_number(axis) if value is None: - - if self._is_mixed_type and axis == 1: + if len(self._mgr.blocks) > 1 and axis == 1: if inplace: raise NotImplementedError() result = self.T.fillna(method=method, limit=limit).T diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 7b4b779e80481..9c985b1752222 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1547,8 +1547,7 @@ def _setitem_with_indexer(self, indexer, value): info_axis = self.obj._info_axis_number # maybe partial set - # _is_mixed_type has the side effect of consolidating in-place - take_split_path = self.obj._is_mixed_type + take_split_path = len(self.obj._mgr.blocks) > 1 # if there is only one block/type, still have to take split path # unless the block is one-dimensional or it can hold the value diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index f2480adce89b4..78ef48cc972ed 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -651,12 +651,6 @@ def _consolidate_check(self) -> None: self._is_consolidated = len(dtypes) == len(set(dtypes)) self._known_consolidated = True - @property - def is_mixed_type(self) -> bool: - # Warning, consolidation needs to get checked upstairs - self._consolidate_inplace() - return len(self.blocks) > 1 - @property def is_numeric_mixed_type(self) -> bool: return all(block.is_numeric for block in self.blocks) diff --git a/pandas/tests/frame/test_dtypes.py b/pandas/tests/frame/test_dtypes.py index 53d417dc10014..5917520802519 100644 --- a/pandas/tests/frame/test_dtypes.py +++ b/pandas/tests/frame/test_dtypes.py @@ -230,18 +230,6 @@ def test_constructor_list_str_na(self, string_dtype): def test_is_homogeneous_type(self, data, expected): assert data._is_homogeneous_type is expected - def test_is_homogeneous_type_clears_cache(self): - ser = pd.Series([1, 2, 3]) - df = ser.to_frame("A") - df["B"] = ser - - assert len(df._mgr.blocks) == 2 - - a = df["B"] # caches lookup - df._is_homogeneous_type # _should_ clear cache - assert len(df._mgr.blocks) == 1 - assert df["B"] is not a - def test_asarray_homogenous(self): df = pd.DataFrame({"A": pd.Categorical([1, 2]), "B": pd.Categorical([1, 2])}) result = np.asarray(df) diff --git a/pandas/tests/internals/test_internals.py b/pandas/tests/internals/test_internals.py index 2567f704a4a8d..cd2f5a903d8cc 100644 --- a/pandas/tests/internals/test_internals.py +++ b/pandas/tests/internals/test_internals.py @@ -272,13 +272,6 @@ def test_attrs(self): assert mgr.nblocks == 2 assert len(mgr) == 6 - def test_is_mixed_dtype(self): - assert not create_mgr("a,b:f8").is_mixed_type - assert not create_mgr("a:f8-1; b:f8-2").is_mixed_type - - assert create_mgr("a,b:f8; c,d: f4").is_mixed_type - assert create_mgr("a,b:f8; c,d: object").is_mixed_type - def test_duplicate_ref_loc_failure(self): tmp_mgr = create_mgr("a:bool; a: f8")