@@ -467,9 +467,8 @@ def convert(
467
467
using_cow : bool = False ,
468
468
) -> list [Block ]:
469
469
"""
470
- attempt to coerce any object types to better types return a copy
471
- of the block (if copy = True) by definition we are not an ObjectBlock
472
- here!
470
+ Attempt to coerce any object types to better types. Return a copy
471
+ of the block (if copy = True).
473
472
"""
474
473
if not copy and using_cow :
475
474
return [self .copy (deep = False )]
@@ -678,7 +677,7 @@ def _replace_regex(
678
677
List[Block]
679
678
"""
680
679
if not self ._can_hold_element (to_replace ):
681
- # i.e. only ObjectBlock , but could in principle include a
680
+ # i.e. only if self.is_object is True , but could in principle include a
682
681
# String ExtensionBlock
683
682
if using_cow :
684
683
return [self .copy (deep = False )]
@@ -1269,7 +1268,7 @@ def fillna(
1269
1268
) -> list [Block ]:
1270
1269
"""
1271
1270
fillna on the block with the value. If we fail, then convert to
1272
- ObjectBlock and try again
1271
+ block to hold objects instead and try again
1273
1272
"""
1274
1273
# Caller is responsible for validating limit; if int it is strictly positive
1275
1274
inplace = validate_bool_kwarg (inplace , "inplace" )
@@ -2060,7 +2059,7 @@ def _unstack(
2060
2059
needs_masking : npt .NDArray [np .bool_ ],
2061
2060
):
2062
2061
# ExtensionArray-safe unstack.
2063
- # We override ObjectBlock ._unstack, which unstacks directly on the
2062
+ # We override Block ._unstack, which unstacks directly on the
2064
2063
# values of the array. For EA-backed blocks, this would require
2065
2064
# converting to a 2-D ndarray of objects.
2066
2065
# Instead, we unstack an ndarray of integer positions, followed by
@@ -2096,6 +2095,7 @@ def _unstack(
2096
2095
2097
2096
class NumpyBlock (libinternals .NumpyBlock , Block ):
2098
2097
values : np .ndarray
2098
+ __slots__ = ()
2099
2099
2100
2100
@property
2101
2101
def is_view (self ) -> bool :
@@ -2114,10 +2114,59 @@ def get_values(self, dtype: DtypeObj | None = None) -> np.ndarray:
2114
2114
def values_for_json (self ) -> np .ndarray :
2115
2115
return self .values
2116
2116
2117
+ @cache_readonly
2118
+ def is_numeric (self ) -> bool :
2119
+ dtype = self .values .dtype
2120
+ kind = dtype .kind
2117
2121
2118
- class NumericBlock (NumpyBlock ):
2119
- __slots__ = ()
2120
- is_numeric = True
2122
+ if kind in "fciub" :
2123
+ return True
2124
+ else :
2125
+ return False
2126
+
2127
+ @cache_readonly
2128
+ def is_object (self ) -> bool :
2129
+ if self .values .dtype .kind == "O" :
2130
+ return True
2131
+ else :
2132
+ return False
2133
+
2134
+ @maybe_split
2135
+ def convert (
2136
+ self ,
2137
+ * ,
2138
+ copy : bool = True ,
2139
+ using_cow : bool = False ,
2140
+ ) -> list [Block ]:
2141
+ """
2142
+ Attempt to coerce any object types to better types. Return a copy
2143
+ of the block (if copy = True).
2144
+ """
2145
+ if not self .is_object :
2146
+ return super ().convert (copy = copy , using_cow = using_cow )
2147
+
2148
+ values = self .values
2149
+ if values .ndim == 2 :
2150
+ # maybe_split ensures we only get here with values.shape[0] == 1,
2151
+ # avoid doing .ravel as that might make a copy
2152
+ values = values [0 ]
2153
+
2154
+ res_values = lib .maybe_convert_objects (
2155
+ values ,
2156
+ convert_datetime = True ,
2157
+ convert_timedelta = True ,
2158
+ convert_period = True ,
2159
+ convert_interval = True ,
2160
+ )
2161
+ refs = None
2162
+ if copy and res_values is values :
2163
+ res_values = values .copy ()
2164
+ elif res_values is values and using_cow :
2165
+ refs = self .refs
2166
+
2167
+ res_values = ensure_block_shape (res_values , self .ndim )
2168
+ res_values = maybe_coerce_values (res_values )
2169
+ return [self .make_block (res_values , refs = refs )]
2121
2170
2122
2171
2123
2172
class NDArrayBackedExtensionBlock (libinternals .NDArrayBackedBlock , EABackedBlock ):
@@ -2253,52 +2302,6 @@ class DatetimeTZBlock(DatetimeLikeBlock):
2253
2302
values_for_json = NDArrayBackedExtensionBlock .values_for_json
2254
2303
2255
2304
2256
- class ObjectBlock (NumpyBlock ):
2257
- __slots__ = ()
2258
- is_object = True
2259
-
2260
- @maybe_split
2261
- def convert (
2262
- self ,
2263
- * ,
2264
- copy : bool = True ,
2265
- using_cow : bool = False ,
2266
- ) -> list [Block ]:
2267
- """
2268
- attempt to cast any object types to better types return a copy of
2269
- the block (if copy = True) by definition we ARE an ObjectBlock!!!!!
2270
- """
2271
- if self .dtype != _dtype_obj :
2272
- # GH#50067 this should be impossible in ObjectBlock, but until
2273
- # that is fixed, we short-circuit here.
2274
- if using_cow :
2275
- return [self .copy (deep = False )]
2276
- return [self ]
2277
-
2278
- values = self .values
2279
- if values .ndim == 2 :
2280
- # maybe_split ensures we only get here with values.shape[0] == 1,
2281
- # avoid doing .ravel as that might make a copy
2282
- values = values [0 ]
2283
-
2284
- res_values = lib .maybe_convert_objects (
2285
- values ,
2286
- convert_datetime = True ,
2287
- convert_timedelta = True ,
2288
- convert_period = True ,
2289
- convert_interval = True ,
2290
- )
2291
- refs = None
2292
- if copy and res_values is values :
2293
- res_values = values .copy ()
2294
- elif res_values is values and using_cow :
2295
- refs = self .refs
2296
-
2297
- res_values = ensure_block_shape (res_values , self .ndim )
2298
- res_values = maybe_coerce_values (res_values )
2299
- return [self .make_block (res_values , refs = refs )]
2300
-
2301
-
2302
2305
# -----------------------------------------------------------------
2303
2306
# Constructor Helpers
2304
2307
@@ -2357,10 +2360,8 @@ def get_block_type(dtype: DtypeObj) -> type[Block]:
2357
2360
kind = dtype .kind
2358
2361
if kind in "Mm" :
2359
2362
return DatetimeLikeBlock
2360
- elif kind in "fciub" :
2361
- return NumericBlock
2362
2363
2363
- return ObjectBlock
2364
+ return NumpyBlock
2364
2365
2365
2366
2366
2367
def new_block_2d (
0 commit comments