@@ -110,6 +110,13 @@ class BaseMaskedArray(OpsMixin, ExtensionArray):
110
110
_truthy_value = Scalar # bool(_truthy_value) = True
111
111
_falsey_value = Scalar # bool(_falsey_value) = False
112
112
113
+ @classmethod
114
+ def _simple_new (cls , values : np .ndarray , mask : npt .NDArray [np .bool_ ]) -> Self :
115
+ result = BaseMaskedArray .__new__ (cls )
116
+ result ._data = values
117
+ result ._mask = mask
118
+ return result
119
+
113
120
def __init__ (
114
121
self , values : np .ndarray , mask : npt .NDArray [np .bool_ ], copy : bool = False
115
122
) -> None :
@@ -169,7 +176,7 @@ def __getitem__(self, item: PositionalIndexer) -> Self | Any:
169
176
return self .dtype .na_value
170
177
return self ._data [item ]
171
178
172
- return type ( self ) (self ._data [item ], newmask )
179
+ return self . _simple_new (self ._data [item ], newmask )
173
180
174
181
@doc (ExtensionArray .fillna )
175
182
def fillna (self , value = None , method = None , limit : int | None = None ) -> Self :
@@ -185,7 +192,7 @@ def fillna(self, value=None, method=None, limit: int | None = None) -> Self:
185
192
npvalues = self ._data .copy ().T
186
193
new_mask = mask .copy ().T
187
194
func (npvalues , limit = limit , mask = new_mask )
188
- return type ( self ) (npvalues .T , new_mask .T )
195
+ return self . _simple_new (npvalues .T , new_mask .T )
189
196
else :
190
197
# fill with value
191
198
new_values = self .copy ()
@@ -282,17 +289,17 @@ def ndim(self) -> int:
282
289
def swapaxes (self , axis1 , axis2 ) -> Self :
283
290
data = self ._data .swapaxes (axis1 , axis2 )
284
291
mask = self ._mask .swapaxes (axis1 , axis2 )
285
- return type ( self ) (data , mask )
292
+ return self . _simple_new (data , mask )
286
293
287
294
def delete (self , loc , axis : AxisInt = 0 ) -> Self :
288
295
data = np .delete (self ._data , loc , axis = axis )
289
296
mask = np .delete (self ._mask , loc , axis = axis )
290
- return type ( self ) (data , mask )
297
+ return self . _simple_new (data , mask )
291
298
292
299
def reshape (self , * args , ** kwargs ) -> Self :
293
300
data = self ._data .reshape (* args , ** kwargs )
294
301
mask = self ._mask .reshape (* args , ** kwargs )
295
- return type ( self ) (data , mask )
302
+ return self . _simple_new (data , mask )
296
303
297
304
def ravel (self , * args , ** kwargs ) -> Self :
298
305
# TODO: need to make sure we have the same order for data/mask
@@ -302,7 +309,7 @@ def ravel(self, *args, **kwargs) -> Self:
302
309
303
310
@property
304
311
def T (self ) -> Self :
305
- return type ( self ) (self ._data .T , self ._mask .T )
312
+ return self . _simple_new (self ._data .T , self ._mask .T )
306
313
307
314
def round (self , decimals : int = 0 , * args , ** kwargs ):
308
315
"""
@@ -338,16 +345,16 @@ def round(self, decimals: int = 0, *args, **kwargs):
338
345
# Unary Methods
339
346
340
347
def __invert__ (self ) -> Self :
341
- return type ( self ) (~ self ._data , self ._mask .copy ())
348
+ return self . _simple_new (~ self ._data , self ._mask .copy ())
342
349
343
350
def __neg__ (self ) -> Self :
344
- return type ( self ) (- self ._data , self ._mask .copy ())
351
+ return self . _simple_new (- self ._data , self ._mask .copy ())
345
352
346
353
def __pos__ (self ) -> Self :
347
354
return self .copy ()
348
355
349
356
def __abs__ (self ) -> Self :
350
- return type ( self ) (abs (self ._data ), self ._mask .copy ())
357
+ return self . _simple_new (abs (self ._data ), self ._mask .copy ())
351
358
352
359
# ------------------------------------------------------------------
353
360
@@ -868,7 +875,7 @@ def take(
868
875
result [fill_mask ] = fill_value
869
876
mask = mask ^ fill_mask
870
877
871
- return type ( self ) (result , mask , copy = False )
878
+ return self . _simple_new (result , mask )
872
879
873
880
# error: Return type "BooleanArray" of "isin" incompatible with return type
874
881
# "ndarray" in supertype "ExtensionArray"
@@ -893,10 +900,9 @@ def isin(self, values) -> BooleanArray: # type: ignore[override]
893
900
return BooleanArray (result , mask , copy = False )
894
901
895
902
def copy (self ) -> Self :
896
- data , mask = self ._data , self ._mask
897
- data = data .copy ()
898
- mask = mask .copy ()
899
- return type (self )(data , mask , copy = False )
903
+ data = self ._data .copy ()
904
+ mask = self ._mask .copy ()
905
+ return self ._simple_new (data , mask )
900
906
901
907
def unique (self ) -> Self :
902
908
"""
@@ -907,7 +913,7 @@ def unique(self) -> Self:
907
913
uniques : BaseMaskedArray
908
914
"""
909
915
uniques , mask = algos .unique_with_mask (self ._data , self ._mask )
910
- return type ( self ) (uniques , mask , copy = False )
916
+ return self . _simple_new (uniques , mask )
911
917
912
918
@doc (ExtensionArray .searchsorted )
913
919
def searchsorted (
@@ -959,7 +965,7 @@ def factorize(
959
965
# dummy value for uniques; not used since uniques_mask will be True
960
966
uniques = np .insert (uniques , na_code , 0 )
961
967
uniques_mask [na_code ] = True
962
- uniques_ea = type ( self ) (uniques , uniques_mask )
968
+ uniques_ea = self . _simple_new (uniques , uniques_mask )
963
969
964
970
return codes , uniques_ea
965
971
@@ -1374,7 +1380,7 @@ def _accumulate(
1374
1380
op = getattr (masked_accumulations , name )
1375
1381
data , mask = op (data , mask , skipna = skipna , ** kwargs )
1376
1382
1377
- return type ( self ) (data , mask , copy = False )
1383
+ return self . _simple_new (data , mask )
1378
1384
1379
1385
# ------------------------------------------------------------------
1380
1386
# GroupBy Methods
0 commit comments