Skip to content

Commit 8e38f28

Browse files
authored
ENH: EA._hasnans, EADtype.empty (#45024)
1 parent 0f3c5e9 commit 8e38f28

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

pandas/core/arrays/base.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def __contains__(self, item: object) -> bool | np.bool_:
425425
if not self._can_hold_na:
426426
return False
427427
elif item is self.dtype.na_value or isinstance(item, self.dtype.type):
428-
return self.isna().any()
428+
return self._hasnans
429429
else:
430430
return False
431431
else:
@@ -603,6 +603,16 @@ def isna(self) -> np.ndarray | ExtensionArraySupportsAnyAll:
603603
"""
604604
raise AbstractMethodError(self)
605605

606+
@property
607+
def _hasnans(self) -> bool:
608+
# GH#22680
609+
"""
610+
Equivalent to `self.isna().any()`.
611+
612+
Some ExtensionArray subclasses may be able to optimize this check.
613+
"""
614+
return bool(self.isna().any())
615+
606616
def _values_for_argsort(self) -> np.ndarray:
607617
"""
608618
Return values for sorting.
@@ -686,7 +696,7 @@ def argmin(self, skipna: bool = True) -> int:
686696
ExtensionArray.argmax
687697
"""
688698
validate_bool_kwarg(skipna, "skipna")
689-
if not skipna and self.isna().any():
699+
if not skipna and self._hasnans:
690700
raise NotImplementedError
691701
return nargminmax(self, "argmin")
692702

@@ -710,7 +720,7 @@ def argmax(self, skipna: bool = True) -> int:
710720
ExtensionArray.argmin
711721
"""
712722
validate_bool_kwarg(skipna, "skipna")
713-
if not skipna and self.isna().any():
723+
if not skipna and self._hasnans:
714724
raise NotImplementedError
715725
return nargminmax(self, "argmax")
716726

pandas/core/dtypes/base.py

+14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from pandas._libs.hashtable import object_hash
1818
from pandas._typing import (
1919
DtypeObj,
20+
Shape,
2021
npt,
2122
type_t,
2223
)
@@ -208,6 +209,19 @@ def construct_array_type(cls) -> type_t[ExtensionArray]:
208209
"""
209210
raise AbstractMethodError(cls)
210211

212+
def empty(self, shape: Shape) -> type_t[ExtensionArray]:
213+
"""
214+
Construct an ExtensionArray of this dtype with the given shape.
215+
216+
Analogous to numpy.empty.
217+
218+
Returns
219+
-------
220+
ExtensionArray
221+
"""
222+
cls = self.construct_array_type()
223+
return cls._empty(shape, dtype=self)
224+
211225
@classmethod
212226
def construct_from_string(
213227
cls: type_t[ExtensionDtypeT], string: str

pandas/tests/extension/base/constructors.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ def test_construct_empty_dataframe(self, dtype):
126126
def test_empty(self, dtype):
127127
cls = dtype.construct_array_type()
128128
result = cls._empty((4,), dtype=dtype)
129-
130129
assert isinstance(result, cls)
131130
assert result.dtype == dtype
131+
assert result.shape == (4,)
132+
133+
# GH#19600 method on ExtensionDtype
134+
result2 = dtype.empty((4,))
135+
assert isinstance(result2, cls)
136+
assert result2.dtype == dtype
137+
assert result2.shape == (4,)

0 commit comments

Comments
 (0)