Skip to content

Commit 6ab50c4

Browse files
authored
REF: share _maybe_coerce_values (pandas-dev#39939)
1 parent dfb92d0 commit 6ab50c4

File tree

1 file changed

+20
-50
lines changed

1 file changed

+20
-50
lines changed

pandas/core/internals/blocks.py

+20-50
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
from pandas._libs import (
1919
Interval,
20-
NaT,
2120
Period,
2221
Timestamp,
2322
algos as libalgos,
@@ -45,6 +44,7 @@
4544
maybe_downcast_numeric,
4645
maybe_downcast_to_dtype,
4746
maybe_upcast,
47+
sanitize_to_nanoseconds,
4848
soft_convert_objects,
4949
)
5050
from pandas.core.dtypes.common import (
@@ -72,6 +72,7 @@
7272
from pandas.core.dtypes.missing import (
7373
is_valid_na_for_dtype,
7474
isna,
75+
na_value_for_dtype,
7576
)
7677

7778
import pandas.core.algorithms as algos
@@ -95,11 +96,13 @@
9596
DatetimeArray,
9697
ExtensionArray,
9798
PandasArray,
98-
TimedeltaArray,
9999
)
100100
from pandas.core.base import PandasObject
101101
import pandas.core.common as com
102-
from pandas.core.construction import extract_array
102+
from pandas.core.construction import (
103+
ensure_wrapped_if_datetimelike,
104+
extract_array,
105+
)
103106
from pandas.core.indexers import (
104107
check_setitem_lengths,
105108
is_empty_indexer,
@@ -2095,8 +2098,6 @@ class DatetimeLikeBlockMixin(NDArrayBackedExtensionBlock):
20952098

20962099
is_numeric = False
20972100
_can_hold_na = True
2098-
_dtype: np.dtype
2099-
_holder: Type[Union[DatetimeArray, TimedeltaArray]]
21002101

21012102
@classmethod
21022103
def _maybe_coerce_values(cls, values):
@@ -2112,25 +2113,26 @@ def _maybe_coerce_values(cls, values):
21122113
Returns
21132114
-------
21142115
values : ndarray[datetime64ns/timedelta64ns]
2115-
2116-
Overridden by DatetimeTZBlock.
21172116
"""
2118-
if values.dtype != cls._dtype:
2119-
# non-nano we will convert to nano
2120-
if values.dtype.kind != cls._dtype.kind:
2121-
# caller is responsible for ensuring td64/dt64 dtype
2122-
raise TypeError(values.dtype) # pragma: no cover
2123-
2124-
values = cls._holder._from_sequence(values)._data
2125-
2126-
if isinstance(values, cls._holder):
2117+
values = extract_array(values, extract_numpy=True)
2118+
if isinstance(values, np.ndarray):
2119+
values = sanitize_to_nanoseconds(values)
2120+
elif isinstance(values.dtype, np.dtype):
2121+
# i.e. not datetime64tz
21272122
values = values._data
21282123

2129-
assert isinstance(values, np.ndarray), type(values)
21302124
return values
21312125

21322126
def array_values(self):
2133-
return self._holder._simple_new(self.values)
2127+
return ensure_wrapped_if_datetimelike(self.values)
2128+
2129+
@property
2130+
def _holder(self):
2131+
return type(self.array_values())
2132+
2133+
@property
2134+
def fill_value(self):
2135+
return na_value_for_dtype(self.dtype)
21342136

21352137
def to_native_types(self, na_rep="NaT", **kwargs):
21362138
""" convert to our native types format """
@@ -2142,9 +2144,6 @@ def to_native_types(self, na_rep="NaT", **kwargs):
21422144

21432145
class DatetimeBlock(DatetimeLikeBlockMixin):
21442146
__slots__ = ()
2145-
fill_value = np.datetime64("NaT", "ns")
2146-
_dtype = fill_value.dtype
2147-
_holder = DatetimeArray
21482147

21492148
def set_inplace(self, locs, values):
21502149
"""
@@ -2165,42 +2164,16 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
21652164
_can_hold_na = True
21662165
is_numeric = False
21672166

2168-
_holder = DatetimeArray
2169-
21702167
internal_values = Block.internal_values
21712168
_can_hold_element = DatetimeBlock._can_hold_element
21722169
to_native_types = DatetimeBlock.to_native_types
21732170
diff = DatetimeBlock.diff
2174-
fill_value = NaT
21752171
where = DatetimeBlock.where
21762172
putmask = DatetimeLikeBlockMixin.putmask
21772173
fillna = DatetimeLikeBlockMixin.fillna
21782174

21792175
array_values = ExtensionBlock.array_values
21802176

2181-
@classmethod
2182-
def _maybe_coerce_values(cls, values):
2183-
"""
2184-
Input validation for values passed to __init__. Ensure that
2185-
we have datetime64TZ, coercing if necessary.
2186-
2187-
Parameters
2188-
----------
2189-
values : array-like
2190-
Must be convertible to datetime64
2191-
2192-
Returns
2193-
-------
2194-
values : DatetimeArray
2195-
"""
2196-
if not isinstance(values, cls._holder):
2197-
values = cls._holder(values)
2198-
2199-
if values.tz is None:
2200-
raise ValueError("cannot create a DatetimeTZBlock without a tz")
2201-
2202-
return values
2203-
22042177
@property
22052178
def is_view(self) -> bool:
22062179
""" return a boolean if I am possibly a view """
@@ -2216,9 +2189,6 @@ def external_values(self):
22162189

22172190
class TimeDeltaBlock(DatetimeLikeBlockMixin):
22182191
__slots__ = ()
2219-
_holder = TimedeltaArray
2220-
fill_value = np.timedelta64("NaT", "ns")
2221-
_dtype = fill_value.dtype
22222192

22232193

22242194
class ObjectBlock(Block):

0 commit comments

Comments
 (0)