Skip to content

Commit 8174f60

Browse files
committed
CLN: de-duplicate should_store, get_values, array_values
1 parent bed9103 commit 8174f60

File tree

1 file changed

+28
-55
lines changed

1 file changed

+28
-55
lines changed

pandas/core/internals/blocks.py

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,20 @@ def _can_hold_element(self, element: Any) -> bool:
653653
return issubclass(tipo.type, dtype)
654654
return isinstance(element, dtype)
655655

656+
def should_store(self, value: ArrayLike) -> bool:
657+
"""
658+
Should we set self.values[indexer] = value inplace or do we need to cast?
659+
660+
Parameters
661+
----------
662+
value : np.ndarray or ExtensionArray
663+
664+
Returns
665+
-------
666+
bool
667+
"""
668+
return is_dtype_equal(value.dtype, self.dtype)
669+
656670
def to_native_types(self, slicer=None, na_rep="nan", quoting=None, **kwargs):
657671
""" convert to our native types format, slicing if desired """
658672
values = self.values
@@ -1752,10 +1766,7 @@ def setitem(self, indexer, value):
17521766

17531767
def get_values(self, dtype=None):
17541768
# ExtensionArrays must be iterable, so this works.
1755-
values = np.asarray(self.values)
1756-
if values.ndim == self.ndim - 1:
1757-
values = values.reshape((1,) + values.shape)
1758-
return values
1769+
return np.asarray(self.values).reshape(self.shape)
17591770

17601771
def array_values(self) -> ExtensionArray:
17611772
return self.values
@@ -2021,11 +2032,6 @@ def to_native_types(
20212032
)
20222033
return formatter.get_result_as_array()
20232034

2024-
def should_store(self, value: ArrayLike) -> bool:
2025-
# when inserting a column should not coerce integers to floats
2026-
# unnecessarily
2027-
return issubclass(value.dtype.type, np.floating) and value.dtype == self.dtype
2028-
20292035

20302036
class ComplexBlock(FloatOrComplexBlock):
20312037
__slots__ = ()
@@ -2058,9 +2064,6 @@ def _can_hold_element(self, element: Any) -> bool:
20582064
)
20592065
return is_integer(element)
20602066

2061-
def should_store(self, value: ArrayLike) -> bool:
2062-
return is_integer_dtype(value) and value.dtype == self.dtype
2063-
20642067

20652068
class DatetimeLikeBlockMixin:
20662069
"""Mixin class for DatetimeBlock, DatetimeTZBlock, and TimedeltaBlock."""
@@ -2069,9 +2072,6 @@ class DatetimeLikeBlockMixin:
20692072
def _holder(self):
20702073
return DatetimeArray
20712074

2072-
def should_store(self, value):
2073-
return is_dtype_equal(self.dtype, value.dtype)
2074-
20752075
@property
20762076
def fill_value(self):
20772077
return np.datetime64("NaT", "ns")
@@ -2081,15 +2081,16 @@ def get_values(self, dtype=None):
20812081
return object dtype as boxed values, such as Timestamps/Timedelta
20822082
"""
20832083
if is_object_dtype(dtype):
2084-
values = self.values.ravel()
2085-
result = self._holder(values).astype(object)
2086-
return result.reshape(self.values.shape)
2084+
return self._holder(self.values).astype(object)
20872085
return self.values
20882086

20892087
def internal_values(self):
20902088
# Override to return DatetimeArray and TimedeltaArray
20912089
return self.array_values()
20922090

2091+
def array_values(self):
2092+
return self._holder(self.values)
2093+
20932094
def iget(self, key):
20942095
# GH#31649 we need to wrap scalars in Timestamp/Timedelta
20952096
# TODO(EA2D): this can be removed if we ever have 2D EA
@@ -2216,12 +2217,6 @@ def set(self, locs, values):
22162217

22172218
self.values[locs] = values
22182219

2219-
def external_values(self):
2220-
return np.asarray(self.values.astype("datetime64[ns]", copy=False))
2221-
2222-
def array_values(self) -> ExtensionArray:
2223-
return DatetimeArray._simple_new(self.values)
2224-
22252220

22262221
class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
22272222
""" implement a datetime64 block with a tz attribute """
@@ -2234,7 +2229,7 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
22342229
_can_hold_element = DatetimeBlock._can_hold_element
22352230
to_native_types = DatetimeBlock.to_native_types
22362231
fill_value = np.datetime64("NaT", "ns")
2237-
should_store = DatetimeBlock.should_store
2232+
should_store = Block.should_store
22382233

22392234
@property
22402235
def _holder(self):
@@ -2293,14 +2288,13 @@ def get_values(self, dtype=None):
22932288
if is_object_dtype(dtype):
22942289
values = values.astype(object)
22952290

2296-
values = np.asarray(values)
2291+
# TODO(EA2D): reshape uuncessary with 2D EAs
2292+
return np.asarray(values).reshape(self.shape)
22972293

2298-
if self.ndim == 2:
2299-
# Ensure that our shape is correct for DataFrame.
2300-
# ExtensionArrays are always 1-D, even in a DataFrame when
2301-
# the analogous NumPy-backed column would be a 2-D ndarray.
2302-
values = values.reshape(1, -1)
2303-
return values
2294+
def external_values(self):
2295+
# NB: this is different from np.asarray(self.values), since that
2296+
# return an object-dtype ndarray of Timestamps.
2297+
return np.asarray(self.values.astype("datetime64[ns]", copy=False))
23042298

23052299
def _slice(self, slicer):
23062300
""" return a slice of my values """
@@ -2467,12 +2461,6 @@ def to_native_types(self, slicer=None, na_rep=None, quoting=None, **kwargs):
24672461
)
24682462
return rvalues
24692463

2470-
def external_values(self):
2471-
return np.asarray(self.values.astype("timedelta64[ns]", copy=False))
2472-
2473-
def array_values(self) -> ExtensionArray:
2474-
return TimedeltaArray._simple_new(self.values)
2475-
24762464

24772465
class BoolBlock(NumericBlock):
24782466
__slots__ = ()
@@ -2485,11 +2473,6 @@ def _can_hold_element(self, element: Any) -> bool:
24852473
return issubclass(tipo.type, np.bool_)
24862474
return isinstance(element, (bool, np.bool_))
24872475

2488-
def should_store(self, value: ArrayLike) -> bool:
2489-
return issubclass(value.dtype.type, np.bool_) and not is_extension_array_dtype(
2490-
value
2491-
)
2492-
24932476
def replace(
24942477
self, to_replace, value, inplace=False, filter=None, regex=False, convert=True
24952478
):
@@ -2577,15 +2560,6 @@ def _maybe_downcast(self, blocks: List["Block"], downcast=None) -> List["Block"]
25772560
def _can_hold_element(self, element: Any) -> bool:
25782561
return True
25792562

2580-
def should_store(self, value: ArrayLike) -> bool:
2581-
return not (
2582-
issubclass(
2583-
value.dtype.type,
2584-
(np.integer, np.floating, np.complexfloating, np.datetime64, np.bool_),
2585-
)
2586-
or is_extension_array_dtype(value)
2587-
)
2588-
25892563
def replace(
25902564
self, to_replace, value, inplace=False, filter=None, regex=False, convert=True
25912565
):
@@ -2816,6 +2790,8 @@ class CategoricalBlock(ExtensionBlock):
28162790
_can_hold_na = True
28172791
_concatenator = staticmethod(concat_categorical)
28182792

2793+
should_store = Block.should_store
2794+
28192795
def __init__(self, values, placement, ndim=None):
28202796
# coerce to categorical if we can
28212797
values = extract_array(values)
@@ -2826,9 +2802,6 @@ def __init__(self, values, placement, ndim=None):
28262802
def _holder(self):
28272803
return Categorical
28282804

2829-
def should_store(self, arr: ArrayLike):
2830-
return isinstance(arr, self._holder) and is_dtype_equal(self.dtype, arr.dtype)
2831-
28322805
def to_native_types(self, slicer=None, na_rep="", quoting=None, **kwargs):
28332806
""" convert to our native types format, slicing if desired """
28342807
values = self.values

0 commit comments

Comments
 (0)