From a9de168fc4ca032c525b8f030ce3395933654030 Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 2 May 2023 14:45:25 +0100 Subject: [PATCH 1/3] PERF: BaseMaskedArray._empty --- pandas/core/arrays/masked.py | 8 ++++++++ pandas/core/dtypes/base.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index f1df86788ac44..41bb11e4562b7 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -132,6 +132,14 @@ def _from_sequence(cls, scalars, *, dtype=None, copy: bool = False) -> Self: values, mask = cls._coerce_to_array(scalars, dtype=dtype, copy=copy) return cls(values, mask) + @classmethod + @doc(ExtensionArray._empty) + def _empty(cls, shape: Shape, dtype: ExtensionDtype): + values = np.empty(shape, dtype=dtype.type) + values[:] = cls._internal_fill_value + mask = np.ones(shape, dtype=bool) + return cls(values, mask) + @property def dtype(self) -> BaseMaskedDtype: raise AbstractMethodError(self) diff --git a/pandas/core/dtypes/base.py b/pandas/core/dtypes/base.py index 7c05ec1ba33a9..f0e55aa178ec0 100644 --- a/pandas/core/dtypes/base.py +++ b/pandas/core/dtypes/base.py @@ -211,7 +211,7 @@ def construct_array_type(cls) -> type_t[ExtensionArray]: """ raise AbstractMethodError(cls) - def empty(self, shape: Shape) -> type_t[ExtensionArray]: + def empty(self, shape: Shape) -> ExtensionArray: """ Construct an ExtensionArray of this dtype with the given shape. From 55067baf2292791ac45cb864c8c820ba331f089f Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 2 May 2023 17:13:23 +0100 Subject: [PATCH 2/3] update --- pandas/core/arrays/masked.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index 41bb11e4562b7..83ac93f0223c0 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -138,7 +138,12 @@ def _empty(cls, shape: Shape, dtype: ExtensionDtype): values = np.empty(shape, dtype=dtype.type) values[:] = cls._internal_fill_value mask = np.ones(shape, dtype=bool) - return cls(values, mask) + result = cls(values, mask) + if not isinstance(result, cls) or dtype != result.dtype: + raise NotImplementedError( + f"Default 'empty' implementation is invalid for dtype='{dtype}'" + ) + return result @property def dtype(self) -> BaseMaskedDtype: From 0abf7e3a9b003d8974b6aedf7f132c8ef46f2ead Mon Sep 17 00:00:00 2001 From: Terji Petersen Date: Tue, 2 May 2023 18:12:21 +0100 Subject: [PATCH 3/3] use .fill method --- pandas/core/arrays/masked.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/masked.py b/pandas/core/arrays/masked.py index 83ac93f0223c0..7c30d53522ad9 100644 --- a/pandas/core/arrays/masked.py +++ b/pandas/core/arrays/masked.py @@ -136,7 +136,7 @@ def _from_sequence(cls, scalars, *, dtype=None, copy: bool = False) -> Self: @doc(ExtensionArray._empty) def _empty(cls, shape: Shape, dtype: ExtensionDtype): values = np.empty(shape, dtype=dtype.type) - values[:] = cls._internal_fill_value + values.fill(cls._internal_fill_value) mask = np.ones(shape, dtype=bool) result = cls(values, mask) if not isinstance(result, cls) or dtype != result.dtype: