7
7
Callable ,
8
8
List ,
9
9
Optional ,
10
+ Tuple ,
10
11
Type ,
11
12
Union ,
12
13
cast ,
47
48
)
48
49
from pandas .core .dtypes .common import (
49
50
is_categorical_dtype ,
50
- is_datetime64tz_dtype ,
51
51
is_dtype_equal ,
52
52
is_extension_array_dtype ,
53
53
is_list_like ,
@@ -164,21 +164,10 @@ def __init__(self, values, placement, ndim: int):
164
164
ndim : int
165
165
1 for SingleBlockManager/Series, 2 for BlockManager/DataFrame
166
166
"""
167
- # TODO(EA2D): ndim will be unnecessary with 2D EAs
168
- self .ndim = self ._check_ndim (values , ndim )
167
+ self .ndim = ndim
169
168
self .mgr_locs = placement
170
169
self .values = self ._maybe_coerce_values (values )
171
170
172
- if self ._validate_ndim and self .ndim and len (self .mgr_locs ) != len (self .values ):
173
- raise ValueError (
174
- f"Wrong number of items passed { len (self .values )} , "
175
- f"placement implies { len (self .mgr_locs )} "
176
- )
177
-
178
- elif self .is_extension and self .ndim == 2 and len (self .mgr_locs ) != 1 :
179
- # TODO(EA2D): check unnecessary with 2D EAs
180
- raise AssertionError ("block.size != values.size" )
181
-
182
171
@classmethod
183
172
def _maybe_coerce_values (cls , values ):
184
173
"""
@@ -194,43 +183,6 @@ def _maybe_coerce_values(cls, values):
194
183
"""
195
184
return values
196
185
197
- def _check_ndim (self , values , ndim : int ):
198
- """
199
- ndim inference and validation.
200
-
201
- Infers ndim from 'values' if not provided to __init__.
202
- Validates that values.ndim and ndim are consistent if and only if
203
- the class variable '_validate_ndim' is True.
204
-
205
- Parameters
206
- ----------
207
- values : array-like
208
- ndim : int
209
-
210
- Returns
211
- -------
212
- ndim : int
213
-
214
- Raises
215
- ------
216
- ValueError : the number of dimensions do not match
217
- """
218
- assert isinstance (ndim , int ) # GH#38134 enforce this
219
-
220
- if self ._validate_ndim :
221
- if values .ndim != ndim :
222
- raise ValueError (
223
- "Wrong number of dimensions. "
224
- f"values.ndim != ndim [{ values .ndim } != { ndim } ]"
225
- )
226
- elif values .ndim > ndim :
227
- # ExtensionBlock
228
- raise ValueError (
229
- "Wrong number of dimensions. "
230
- f"values.ndim > ndim [{ values .ndim } > { ndim } ]"
231
- )
232
- return ndim
233
-
234
186
@property
235
187
def _holder (self ):
236
188
"""
@@ -384,7 +336,7 @@ def getitem_block(self, slicer, new_mgr_locs=None) -> Block:
384
336
385
337
new_values = self ._slice (slicer )
386
338
387
- if self . _validate_ndim and new_values .ndim != self .ndim :
339
+ if new_values .ndim != self . values .ndim :
388
340
raise ValueError ("Only same dim slicing is allowed" )
389
341
390
342
return type (self )._simple_new (new_values , new_mgr_locs , self .ndim )
@@ -2337,10 +2289,68 @@ def get_block_type(values, dtype: Optional[Dtype] = None):
2337
2289
return cls
2338
2290
2339
2291
2340
- def new_block (
2341
- values , placement , klass = None , ndim = None , dtype : Optional [Dtype ] = None
2342
- ) -> Block :
2343
- # Ensure that we don't allow PandasArray / PandasDtype in internals.
2292
+ def new_block (values , placement , * , ndim : int , klass = None ) -> Block :
2293
+
2294
+ if not isinstance (placement , BlockPlacement ):
2295
+ placement = BlockPlacement (placement )
2296
+
2297
+ values , _ = extract_pandas_array (values , None , ndim )
2298
+ check_ndim (values , placement , ndim )
2299
+
2300
+ if klass is None :
2301
+ klass = get_block_type (values , values .dtype )
2302
+
2303
+ return klass (values , ndim = ndim , placement = placement )
2304
+
2305
+
2306
+ def check_ndim (values , placement : BlockPlacement , ndim : int ):
2307
+ """
2308
+ ndim inference and validation.
2309
+
2310
+ Validates that values.ndim and ndim are consistent.
2311
+ Validates that len(values) and len(placement) are consistent.
2312
+
2313
+ Parameters
2314
+ ----------
2315
+ values : array-like
2316
+ placement : BlockPlacement
2317
+ ndim : int
2318
+
2319
+ Raises
2320
+ ------
2321
+ ValueError : the number of dimensions do not match
2322
+ """
2323
+
2324
+ if values .ndim > ndim :
2325
+ # Check for both np.ndarray and ExtensionArray
2326
+ raise ValueError (
2327
+ "Wrong number of dimensions. "
2328
+ f"values.ndim > ndim [{ values .ndim } > { ndim } ]"
2329
+ )
2330
+
2331
+ elif isinstance (values .dtype , np .dtype ):
2332
+ # TODO(EA2D): special case not needed with 2D EAs
2333
+ if values .ndim != ndim :
2334
+ raise ValueError (
2335
+ "Wrong number of dimensions. "
2336
+ f"values.ndim != ndim [{ values .ndim } != { ndim } ]"
2337
+ )
2338
+ if len (placement ) != len (values ):
2339
+ raise ValueError (
2340
+ f"Wrong number of items passed { len (values )} , "
2341
+ f"placement implies { len (placement )} "
2342
+ )
2343
+ elif ndim == 2 and len (placement ) != 1 :
2344
+ # TODO(EA2D): special case unnecessary with 2D EAs
2345
+ raise AssertionError ("block.size != values.size" )
2346
+
2347
+
2348
+ def extract_pandas_array (
2349
+ values : ArrayLike , dtype : Optional [DtypeObj ], ndim : int
2350
+ ) -> Tuple [ArrayLike , Optional [DtypeObj ]]:
2351
+ """
2352
+ Ensure that we don't allow PandasArray / PandasDtype in internals.
2353
+ """
2344
2354
# For now, blocks should be backed by ndarrays when possible.
2345
2355
if isinstance (values , ABCPandasArray ):
2346
2356
values = values .to_numpy ()
@@ -2351,16 +2361,7 @@ def new_block(
2351
2361
if isinstance (dtype , PandasDtype ):
2352
2362
dtype = dtype .numpy_dtype
2353
2363
2354
- if klass is None :
2355
- dtype = dtype or values .dtype
2356
- klass = get_block_type (values , dtype )
2357
-
2358
- elif klass is DatetimeTZBlock and not is_datetime64tz_dtype (values .dtype ):
2359
- # TODO: This is no longer hit internally; does it need to be retained
2360
- # for e.g. pyarrow?
2361
- values = DatetimeArray ._simple_new (values , dtype = dtype )
2362
-
2363
- return klass (values , ndim = ndim , placement = placement )
2364
+ return values , dtype
2364
2365
2365
2366
2366
2367
# -----------------------------------------------------------------
0 commit comments