@@ -108,6 +108,13 @@ class BaseMaskedArray(OpsMixin, ExtensionArray):
108
108
_truthy_value = Scalar # bool(_truthy_value) = True
109
109
_falsey_value = Scalar # bool(_falsey_value) = False
110
110
111
+ @classmethod
112
+ def _simple_new (cls , values : np .ndarray , mask : npt .NDArray [np .bool_ ]) -> Self :
113
+ result = BaseMaskedArray .__new__ (cls )
114
+ result ._data = values
115
+ result ._mask = mask
116
+ return result
117
+
111
118
def __init__ (
112
119
self , values : np .ndarray , mask : npt .NDArray [np .bool_ ], copy : bool = False
113
120
) -> None :
@@ -154,7 +161,7 @@ def __getitem__(self, item: PositionalIndexer) -> Self | Any:
154
161
return self .dtype .na_value
155
162
return self ._data [item ]
156
163
157
- return type ( self ) (self ._data [item ], newmask )
164
+ return self . _simple_new (self ._data [item ], newmask )
158
165
159
166
@doc (ExtensionArray .fillna )
160
167
@doc (ExtensionArray .fillna )
@@ -177,7 +184,7 @@ def fillna(self, value=None, method=None, limit: int | None = None) -> Self:
177
184
npvalues = self ._data .copy ().T
178
185
new_mask = mask .copy ().T
179
186
func (npvalues , limit = limit , mask = new_mask )
180
- return type ( self ) (npvalues .T , new_mask .T )
187
+ return self . _simple_new (npvalues .T , new_mask .T )
181
188
else :
182
189
# fill with value
183
190
new_values = self .copy ()
@@ -266,17 +273,17 @@ def ndim(self) -> int:
266
273
def swapaxes (self , axis1 , axis2 ) -> Self :
267
274
data = self ._data .swapaxes (axis1 , axis2 )
268
275
mask = self ._mask .swapaxes (axis1 , axis2 )
269
- return type ( self ) (data , mask )
276
+ return self . _simple_new (data , mask )
270
277
271
278
def delete (self , loc , axis : AxisInt = 0 ) -> Self :
272
279
data = np .delete (self ._data , loc , axis = axis )
273
280
mask = np .delete (self ._mask , loc , axis = axis )
274
- return type ( self ) (data , mask )
281
+ return self . _simple_new (data , mask )
275
282
276
283
def reshape (self , * args , ** kwargs ) -> Self :
277
284
data = self ._data .reshape (* args , ** kwargs )
278
285
mask = self ._mask .reshape (* args , ** kwargs )
279
- return type ( self ) (data , mask )
286
+ return self . _simple_new (data , mask )
280
287
281
288
def ravel (self , * args , ** kwargs ) -> Self :
282
289
# TODO: need to make sure we have the same order for data/mask
@@ -286,7 +293,7 @@ def ravel(self, *args, **kwargs) -> Self:
286
293
287
294
@property
288
295
def T (self ) -> Self :
289
- return type ( self ) (self ._data .T , self ._mask .T )
296
+ return self . _simple_new (self ._data .T , self ._mask .T )
290
297
291
298
def round (self , decimals : int = 0 , * args , ** kwargs ):
292
299
"""
@@ -322,16 +329,16 @@ def round(self, decimals: int = 0, *args, **kwargs):
322
329
# Unary Methods
323
330
324
331
def __invert__ (self ) -> Self :
325
- return type ( self ) (~ self ._data , self ._mask .copy ())
332
+ return self . _simple_new (~ self ._data , self ._mask .copy ())
326
333
327
334
def __neg__ (self ) -> Self :
328
- return type ( self ) (- self ._data , self ._mask .copy ())
335
+ return self . _simple_new (- self ._data , self ._mask .copy ())
329
336
330
337
def __pos__ (self ) -> Self :
331
338
return self .copy ()
332
339
333
340
def __abs__ (self ) -> Self :
334
- return type ( self ) (abs (self ._data ), self ._mask .copy ())
341
+ return self . _simple_new (abs (self ._data ), self ._mask .copy ())
335
342
336
343
# ------------------------------------------------------------------
337
344
@@ -864,7 +871,7 @@ def take(
864
871
result [fill_mask ] = fill_value
865
872
mask = mask ^ fill_mask
866
873
867
- return type ( self ) (result , mask , copy = False )
874
+ return self . _simple_new (result , mask )
868
875
869
876
# error: Return type "BooleanArray" of "isin" incompatible with return type
870
877
# "ndarray" in supertype "ExtensionArray"
@@ -889,10 +896,9 @@ def isin(self, values) -> BooleanArray: # type: ignore[override]
889
896
return BooleanArray (result , mask , copy = False )
890
897
891
898
def copy (self ) -> Self :
892
- data , mask = self ._data , self ._mask
893
- data = data .copy ()
894
- mask = mask .copy ()
895
- return type (self )(data , mask , copy = False )
899
+ data = self ._data .copy ()
900
+ mask = self ._mask .copy ()
901
+ return self ._simple_new (data , mask )
896
902
897
903
def unique (self ) -> Self :
898
904
"""
@@ -903,7 +909,7 @@ def unique(self) -> Self:
903
909
uniques : BaseMaskedArray
904
910
"""
905
911
uniques , mask = algos .unique_with_mask (self ._data , self ._mask )
906
- return type ( self ) (uniques , mask , copy = False )
912
+ return self . _simple_new (uniques , mask )
907
913
908
914
@doc (ExtensionArray .searchsorted )
909
915
def searchsorted (
@@ -955,7 +961,7 @@ def factorize(
955
961
# dummy value for uniques; not used since uniques_mask will be True
956
962
uniques = np .insert (uniques , na_code , 0 )
957
963
uniques_mask [na_code ] = True
958
- uniques_ea = type ( self ) (uniques , uniques_mask )
964
+ uniques_ea = self . _simple_new (uniques , uniques_mask )
959
965
960
966
return codes , uniques_ea
961
967
@@ -1410,7 +1416,7 @@ def _accumulate(
1410
1416
op = getattr (masked_accumulations , name )
1411
1417
data , mask = op (data , mask , skipna = skipna , ** kwargs )
1412
1418
1413
- return type ( self ) (data , mask , copy = False )
1419
+ return self . _simple_new (data , mask )
1414
1420
1415
1421
# ------------------------------------------------------------------
1416
1422
# GroupBy Methods
0 commit comments