9
9
Callable ,
10
10
Hashable ,
11
11
Literal ,
12
- TypeVar ,
13
12
)
14
13
15
14
import numpy as np
92
91
ArrayLike ,
93
92
AxisInt ,
94
93
DtypeObj ,
94
+ Self ,
95
95
QuantileInterpolation ,
96
96
npt ,
97
97
)
98
- T = TypeVar ("T" , bound = "BaseArrayManager" )
99
98
100
99
101
100
class BaseArrayManager (DataManager ):
@@ -131,7 +130,7 @@ def __init__(
131
130
) -> None :
132
131
raise NotImplementedError
133
132
134
- def make_empty (self : T , axes = None ) -> T :
133
+ def make_empty (self , axes = None ) -> Self :
135
134
"""Return an empty ArrayManager with the items axis of len 0 (no columns)"""
136
135
if axes is None :
137
136
axes = [self .axes [1 :], Index ([])]
@@ -195,11 +194,11 @@ def __repr__(self) -> str:
195
194
return output
196
195
197
196
def apply (
198
- self : T ,
197
+ self ,
199
198
f ,
200
199
align_keys : list [str ] | None = None ,
201
200
** kwargs ,
202
- ) -> T :
201
+ ) -> Self :
203
202
"""
204
203
Iterate over the arrays, collect and create a new ArrayManager.
205
204
@@ -257,8 +256,8 @@ def apply(
257
256
return type (self )(result_arrays , new_axes ) # type: ignore[arg-type]
258
257
259
258
def apply_with_block (
260
- self : T , f , align_keys = None , swap_axis : bool = True , ** kwargs
261
- ) -> T :
259
+ self , f , align_keys = None , swap_axis : bool = True , ** kwargs
260
+ ) -> Self :
262
261
# switch axis to follow BlockManager logic
263
262
if swap_axis and "axis" in kwargs and self .ndim == 2 :
264
263
kwargs ["axis" ] = 1 if kwargs ["axis" ] == 0 else 0
@@ -311,7 +310,7 @@ def apply_with_block(
311
310
312
311
return type (self )(result_arrays , self ._axes )
313
312
314
- def where (self : T , other , cond , align : bool ) -> T :
313
+ def where (self , other , cond , align : bool ) -> Self :
315
314
if align :
316
315
align_keys = ["other" , "cond" ]
317
316
else :
@@ -325,13 +324,13 @@ def where(self: T, other, cond, align: bool) -> T:
325
324
cond = cond ,
326
325
)
327
326
328
- def round (self : T , decimals : int , using_cow : bool = False ) -> T :
327
+ def round (self , decimals : int , using_cow : bool = False ) -> Self :
329
328
return self .apply_with_block ("round" , decimals = decimals , using_cow = using_cow )
330
329
331
- def setitem (self : T , indexer , value ) -> T :
330
+ def setitem (self , indexer , value ) -> Self :
332
331
return self .apply_with_block ("setitem" , indexer = indexer , value = value )
333
332
334
- def putmask (self : T , mask , new , align : bool = True ) -> T :
333
+ def putmask (self , mask , new , align : bool = True ) -> Self :
335
334
if align :
336
335
align_keys = ["new" , "mask" ]
337
336
else :
@@ -345,14 +344,14 @@ def putmask(self: T, mask, new, align: bool = True) -> T:
345
344
new = new ,
346
345
)
347
346
348
- def diff (self : T , n : int , axis : AxisInt ) -> T :
347
+ def diff (self , n : int , axis : AxisInt ) -> Self :
349
348
assert self .ndim == 2 and axis == 0 # caller ensures
350
349
return self .apply (algos .diff , n = n , axis = axis )
351
350
352
- def interpolate (self : T , ** kwargs ) -> T :
351
+ def interpolate (self , ** kwargs ) -> Self :
353
352
return self .apply_with_block ("interpolate" , swap_axis = False , ** kwargs )
354
353
355
- def shift (self : T , periods : int , axis : AxisInt , fill_value ) -> T :
354
+ def shift (self , periods : int , axis : AxisInt , fill_value ) -> Self :
356
355
if fill_value is lib .no_default :
357
356
fill_value = None
358
357
@@ -364,7 +363,7 @@ def shift(self: T, periods: int, axis: AxisInt, fill_value) -> T:
364
363
"shift" , periods = periods , axis = axis , fill_value = fill_value
365
364
)
366
365
367
- def fillna (self : T , value , limit , inplace : bool , downcast ) -> T :
366
+ def fillna (self , value , limit , inplace : bool , downcast ) -> Self :
368
367
if limit is not None :
369
368
# Do this validation even if we go through one of the no-op paths
370
369
limit = libalgos .validate_limit (None , limit = limit )
@@ -373,13 +372,13 @@ def fillna(self: T, value, limit, inplace: bool, downcast) -> T:
373
372
"fillna" , value = value , limit = limit , inplace = inplace , downcast = downcast
374
373
)
375
374
376
- def astype (self : T , dtype , copy : bool | None = False , errors : str = "raise" ) -> T :
375
+ def astype (self , dtype , copy : bool | None = False , errors : str = "raise" ) -> Self :
377
376
if copy is None :
378
377
copy = True
379
378
380
379
return self .apply (astype_array_safe , dtype = dtype , copy = copy , errors = errors )
381
380
382
- def convert (self : T , copy : bool | None ) -> T :
381
+ def convert (self , copy : bool | None ) -> Self :
383
382
if copy is None :
384
383
copy = True
385
384
@@ -402,10 +401,10 @@ def _convert(arr):
402
401
403
402
return self .apply (_convert )
404
403
405
- def replace_regex (self : T , ** kwargs ) -> T :
404
+ def replace_regex (self , ** kwargs ) -> Self :
406
405
return self .apply_with_block ("_replace_regex" , ** kwargs )
407
406
408
- def replace (self : T , to_replace , value , inplace : bool ) -> T :
407
+ def replace (self , to_replace , value , inplace : bool ) -> Self :
409
408
inplace = validate_bool_kwarg (inplace , "inplace" )
410
409
assert np .ndim (value ) == 0 , value
411
410
# TODO "replace" is right now implemented on the blocks, we should move
@@ -415,12 +414,12 @@ def replace(self: T, to_replace, value, inplace: bool) -> T:
415
414
)
416
415
417
416
def replace_list (
418
- self : T ,
417
+ self ,
419
418
src_list : list [Any ],
420
419
dest_list : list [Any ],
421
420
inplace : bool = False ,
422
421
regex : bool = False ,
423
- ) -> T :
422
+ ) -> Self :
424
423
"""do a list replace"""
425
424
inplace = validate_bool_kwarg (inplace , "inplace" )
426
425
@@ -432,7 +431,7 @@ def replace_list(
432
431
regex = regex ,
433
432
)
434
433
435
- def to_native_types (self : T , ** kwargs ) -> T :
434
+ def to_native_types (self , ** kwargs ) -> Self :
436
435
return self .apply (to_native_types , ** kwargs )
437
436
438
437
@property
@@ -458,7 +457,7 @@ def is_view(self) -> bool:
458
457
def is_single_block (self ) -> bool :
459
458
return len (self .arrays ) == 1
460
459
461
- def _get_data_subset (self : T , predicate : Callable ) -> T :
460
+ def _get_data_subset (self , predicate : Callable ) -> Self :
462
461
indices = [i for i , arr in enumerate (self .arrays ) if predicate (arr )]
463
462
arrays = [self .arrays [i ] for i in indices ]
464
463
# TODO copy?
@@ -469,7 +468,7 @@ def _get_data_subset(self: T, predicate: Callable) -> T:
469
468
new_axes = [self ._axes [0 ], new_cols ]
470
469
return type (self )(arrays , new_axes , verify_integrity = False )
471
470
472
- def get_bool_data (self : T , copy : bool = False ) -> T :
471
+ def get_bool_data (self , copy : bool = False ) -> Self :
473
472
"""
474
473
Select columns that are bool-dtype and object-dtype columns that are all-bool.
475
474
@@ -480,7 +479,7 @@ def get_bool_data(self: T, copy: bool = False) -> T:
480
479
"""
481
480
return self ._get_data_subset (lambda x : x .dtype == np .dtype (bool ))
482
481
483
- def get_numeric_data (self : T , copy : bool = False ) -> T :
482
+ def get_numeric_data (self , copy : bool = False ) -> Self :
484
483
"""
485
484
Select columns that have a numeric dtype.
486
485
@@ -494,7 +493,7 @@ def get_numeric_data(self: T, copy: bool = False) -> T:
494
493
or getattr (arr .dtype , "_is_numeric" , False )
495
494
)
496
495
497
- def copy (self : T , deep : bool | Literal ["all" ] | None = True ) -> T :
496
+ def copy (self , deep : bool | Literal ["all" ] | None = True ) -> Self :
498
497
"""
499
498
Make deep or shallow copy of ArrayManager
500
499
@@ -531,7 +530,7 @@ def copy_func(ax):
531
530
return type (self )(new_arrays , new_axes , verify_integrity = False )
532
531
533
532
def reindex_indexer (
534
- self : T ,
533
+ self ,
535
534
new_axis ,
536
535
indexer ,
537
536
axis : AxisInt ,
@@ -542,7 +541,7 @@ def reindex_indexer(
542
541
only_slice : bool = False ,
543
542
# ArrayManager specific keywords
544
543
use_na_proxy : bool = False ,
545
- ) -> T :
544
+ ) -> Self :
546
545
axis = self ._normalize_axis (axis )
547
546
return self ._reindex_indexer (
548
547
new_axis ,
@@ -555,15 +554,15 @@ def reindex_indexer(
555
554
)
556
555
557
556
def _reindex_indexer (
558
- self : T ,
557
+ self ,
559
558
new_axis ,
560
559
indexer : npt .NDArray [np .intp ] | None ,
561
560
axis : AxisInt ,
562
561
fill_value = None ,
563
562
allow_dups : bool = False ,
564
563
copy : bool | None = True ,
565
564
use_na_proxy : bool = False ,
566
- ) -> T :
565
+ ) -> Self :
567
566
"""
568
567
Parameters
569
568
----------
@@ -634,11 +633,12 @@ def _reindex_indexer(
634
633
return type (self )(new_arrays , new_axes , verify_integrity = False )
635
634
636
635
def take (
637
- self : T ,
636
+ self ,
638
637
indexer : npt .NDArray [np .intp ],
639
638
axis : AxisInt = 1 ,
640
639
verify : bool = True ,
641
- ) -> T :
640
+ convert_indices : bool = True ,
641
+ ) -> Self :
642
642
"""
643
643
Take items along any axis.
644
644
"""
@@ -926,7 +926,7 @@ def idelete(self, indexer) -> ArrayManager:
926
926
# --------------------------------------------------------------------
927
927
# Array-wise Operation
928
928
929
- def grouped_reduce (self : T , func : Callable ) -> T :
929
+ def grouped_reduce (self , func : Callable ) -> Self :
930
930
"""
931
931
Apply grouped reduction function columnwise, returning a new ArrayManager.
932
932
@@ -965,7 +965,7 @@ def grouped_reduce(self: T, func: Callable) -> T:
965
965
# expected "List[Union[ndarray, ExtensionArray]]"
966
966
return type (self )(result_arrays , [index , columns ]) # type: ignore[arg-type]
967
967
968
- def reduce (self : T , func : Callable ) -> T :
968
+ def reduce (self , func : Callable ) -> Self :
969
969
"""
970
970
Apply reduction function column-wise, returning a single-row ArrayManager.
971
971
0 commit comments