32
32
soft_convert_objects ,
33
33
)
34
34
from pandas .core .dtypes .common import (
35
- DT64NS_DTYPE ,
36
- TD64NS_DTYPE ,
37
35
is_categorical_dtype ,
38
36
is_datetime64_dtype ,
39
37
is_datetime64tz_dtype ,
@@ -143,7 +141,8 @@ def __init__(self, values, placement, ndim: int):
143
141
f"placement implies { len (self .mgr_locs )} "
144
142
)
145
143
146
- def _maybe_coerce_values (self , values ):
144
+ @classmethod
145
+ def _maybe_coerce_values (cls , values ):
147
146
"""
148
147
Ensure we have correctly-typed values.
149
148
@@ -1546,7 +1545,8 @@ def putmask(self, mask, new) -> List[Block]:
1546
1545
new_values [mask ] = new
1547
1546
return [self .make_block (values = new_values )]
1548
1547
1549
- def _maybe_coerce_values (self , values ):
1548
+ @classmethod
1549
+ def _maybe_coerce_values (cls , values ):
1550
1550
"""
1551
1551
Unbox to an extension array.
1552
1552
@@ -1937,13 +1937,39 @@ def to_native_types(
1937
1937
class DatetimeLikeBlockMixin (HybridMixin , Block ):
1938
1938
"""Mixin class for DatetimeBlock, DatetimeTZBlock, and TimedeltaBlock."""
1939
1939
1940
- @property
1941
- def _holder (self ):
1942
- return DatetimeArray
1940
+ _dtype : np .dtype
1941
+ _holder : Type [Union [DatetimeArray , TimedeltaArray ]]
1943
1942
1944
- @property
1945
- def fill_value (self ):
1946
- return np .datetime64 ("NaT" , "ns" )
1943
+ @classmethod
1944
+ def _maybe_coerce_values (cls , values ):
1945
+ """
1946
+ Input validation for values passed to __init__. Ensure that
1947
+ we have nanosecond datetime64/timedelta64, coercing if necessary.
1948
+
1949
+ Parameters
1950
+ ----------
1951
+ values : array-like
1952
+ Must be convertible to datetime64/timedelta64
1953
+
1954
+ Returns
1955
+ -------
1956
+ values : ndarray[datetime64ns/timedelta64ns]
1957
+
1958
+ Overridden by DatetimeTZBlock.
1959
+ """
1960
+ if values .dtype != cls ._dtype :
1961
+ # non-nano we will convert to nano
1962
+ if values .dtype .kind != cls ._dtype .kind :
1963
+ # caller is responsible for ensuring td64/dt64 dtype
1964
+ raise TypeError (values .dtype ) # pragma: no cover
1965
+
1966
+ values = cls ._holder ._from_sequence (values )._data
1967
+
1968
+ if isinstance (values , cls ._holder ):
1969
+ values = values ._data
1970
+
1971
+ assert isinstance (values , np .ndarray ), type (values )
1972
+ return values
1947
1973
1948
1974
def get_values (self , dtype : Optional [DtypeObj ] = None ) -> np .ndarray :
1949
1975
"""
@@ -2039,36 +2065,14 @@ def where(self, other, cond, errors="raise", axis: int = 0) -> List[Block]:
2039
2065
class DatetimeBlock (DatetimeLikeBlockMixin ):
2040
2066
__slots__ = ()
2041
2067
is_datetime = True
2068
+ fill_value = np .datetime64 ("NaT" , "ns" )
2069
+ _dtype = fill_value .dtype
2070
+ _holder = DatetimeArray
2042
2071
2043
2072
@property
2044
2073
def _can_hold_na (self ):
2045
2074
return True
2046
2075
2047
- def _maybe_coerce_values (self , values ):
2048
- """
2049
- Input validation for values passed to __init__. Ensure that
2050
- we have datetime64ns, coercing if necessary.
2051
-
2052
- Parameters
2053
- ----------
2054
- values : array-like
2055
- Must be convertible to datetime64
2056
-
2057
- Returns
2058
- -------
2059
- values : ndarray[datetime64ns]
2060
-
2061
- Overridden by DatetimeTZBlock.
2062
- """
2063
- if values .dtype != DT64NS_DTYPE :
2064
- values = conversion .ensure_datetime64ns (values )
2065
-
2066
- if isinstance (values , DatetimeArray ):
2067
- values = values ._data
2068
-
2069
- assert isinstance (values , np .ndarray ), type (values )
2070
- return values
2071
-
2072
2076
def set_inplace (self , locs , values ):
2073
2077
"""
2074
2078
See Block.set.__doc__
@@ -2087,6 +2091,8 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
2087
2091
is_datetimetz = True
2088
2092
is_extension = True
2089
2093
2094
+ _holder = DatetimeArray
2095
+
2090
2096
internal_values = Block .internal_values
2091
2097
_can_hold_element = DatetimeBlock ._can_hold_element
2092
2098
to_native_types = DatetimeBlock .to_native_types
@@ -2097,11 +2103,8 @@ class DatetimeTZBlock(ExtensionBlock, DatetimeBlock):
2097
2103
2098
2104
array_values = ExtensionBlock .array_values
2099
2105
2100
- @property
2101
- def _holder (self ):
2102
- return DatetimeArray
2103
-
2104
- def _maybe_coerce_values (self , values ):
2106
+ @classmethod
2107
+ def _maybe_coerce_values (cls , values ):
2105
2108
"""
2106
2109
Input validation for values passed to __init__. Ensure that
2107
2110
we have datetime64TZ, coercing if necessary.
@@ -2115,8 +2118,8 @@ def _maybe_coerce_values(self, values):
2115
2118
-------
2116
2119
values : DatetimeArray
2117
2120
"""
2118
- if not isinstance (values , self ._holder ):
2119
- values = self ._holder (values )
2121
+ if not isinstance (values , cls ._holder ):
2122
+ values = cls ._holder (values )
2120
2123
2121
2124
if values .tz is None :
2122
2125
raise ValueError ("cannot create a DatetimeTZBlock without a tz" )
@@ -2207,24 +2210,9 @@ class TimeDeltaBlock(DatetimeLikeBlockMixin):
2207
2210
is_timedelta = True
2208
2211
_can_hold_na = True
2209
2212
is_numeric = False
2213
+ _holder = TimedeltaArray
2210
2214
fill_value = np .timedelta64 ("NaT" , "ns" )
2211
-
2212
- def _maybe_coerce_values (self , values ):
2213
- if values .dtype != TD64NS_DTYPE :
2214
- # non-nano we will convert to nano
2215
- if values .dtype .kind != "m" :
2216
- # caller is responsible for ensuring timedelta64 dtype
2217
- raise TypeError (values .dtype ) # pragma: no cover
2218
-
2219
- values = TimedeltaArray ._from_sequence (values )._data
2220
- if isinstance (values , TimedeltaArray ):
2221
- values = values ._data
2222
- assert isinstance (values , np .ndarray ), type (values )
2223
- return values
2224
-
2225
- @property
2226
- def _holder (self ):
2227
- return TimedeltaArray
2215
+ _dtype = fill_value .dtype
2228
2216
2229
2217
def fillna (
2230
2218
self , value , limit = None , inplace : bool = False , downcast = None
@@ -2240,7 +2228,8 @@ class ObjectBlock(Block):
2240
2228
is_object = True
2241
2229
_can_hold_na = True
2242
2230
2243
- def _maybe_coerce_values (self , values ):
2231
+ @classmethod
2232
+ def _maybe_coerce_values (cls , values ):
2244
2233
if issubclass (values .dtype .type , str ):
2245
2234
values = np .array (values , dtype = object )
2246
2235
return values
0 commit comments