From 1a3b757650e49ab1d3495dc70d3604ea9e47abf7 Mon Sep 17 00:00:00 2001 From: Brock Date: Sun, 24 Jan 2021 16:38:28 -0800 Subject: [PATCH 1/3] CI: fix PandasArray test --- pandas/tests/extension/test_numpy.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/tests/extension/test_numpy.py b/pandas/tests/extension/test_numpy.py index 4e054a07d8ef1..753ad7bb3728d 100644 --- a/pandas/tests/extension/test_numpy.py +++ b/pandas/tests/extension/test_numpy.py @@ -313,6 +313,10 @@ def test_arith_series_with_scalar(self, data, all_arithmetic_operators): def test_arith_series_with_array(self, data, all_arithmetic_operators): super().test_arith_series_with_array(data, all_arithmetic_operators) + @skip_nested + def test_arith_frame_with_scalar(self, data, all_arithmetic_operators): + super().test_arith_frame_with_scalar(data, all_arithmetic_operators) + class TestPrinting(BaseNumPyTests, base.BasePrintingTests): pass From 24c088f614f09a6fdfbc524f01b3de2e4e6edb97 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 25 Jan 2021 13:51:17 -0800 Subject: [PATCH 2/3] ENH: EA.delete --- pandas/core/arrays/base.py | 7 +++++++ pandas/core/arrays/interval.py | 9 +++++++++ pandas/core/indexes/extension.py | 22 +++++++++++----------- pandas/core/indexes/interval.py | 13 ------------- pandas/tests/extension/base/methods.py | 9 +++++++++ 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index ee84ce205db95..4aa5ab2f7b0d3 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -1261,6 +1261,13 @@ def _reduce(self, name: str, *, skipna: bool = True, **kwargs): def __hash__(self): raise TypeError(f"unhashable type: {repr(type(self).__name__)}") + # ------------------------------------------------------------------------ + # Non-Optimized Default Methods + + def delete(self: ExtensionArrayT, loc) -> ExtensionArrayT: + indexer = np.delete(np.arange(len(self)), loc) + return self.take(indexer) + class ExtensionOpsMixin: """ diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 0afcfd86a2de5..882ca0955bc99 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -1413,6 +1413,15 @@ def to_tuples(self, na_tuple=True): # --------------------------------------------------------------------- + def delete(self: IntervalArrayT, loc) -> IntervalArrayT: + if isinstance(self._left, np.ndarray): + new_left = np.delete(self._left, loc) + new_right = np.delete(self._right, loc) + else: + new_left = self._left.delete(loc) + new_right = self._right.delete(loc) + return self._shallow_copy(left=new_left, right=new_right) + @Appender(_extension_array_shared_docs["repeat"] % _shared_docs_kwargs) def repeat(self, repeats, axis=None): nv.validate_repeat((), {"axis": axis}) diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index b25393ca3c58d..75f6658f94680 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -257,6 +257,17 @@ def searchsorted(self, value, side="left", sorter=None) -> np.ndarray: def _get_engine_target(self) -> np.ndarray: return np.asarray(self._data) + def delete(self: _T, loc) -> _T: + """ + Make new Index with passed location(-s) deleted + + Returns + ------- + new_index : Index + """ + arr = self._data.delete(loc) + return type(self)._simple_new(arr, name=self.name) + def repeat(self, repeats, axis=None): nv.validate_repeat((), {"axis": axis}) result = self._data.repeat(repeats, axis=axis) @@ -333,17 +344,6 @@ class NDArrayBackedExtensionIndex(ExtensionIndex): def _get_engine_target(self) -> np.ndarray: return self._data._ndarray - def delete(self: _T, loc) -> _T: - """ - Make new Index with passed location(-s) deleted - - Returns - ------- - new_index : Index - """ - arr = self._data.delete(loc) - return type(self)._simple_new(arr, name=self.name) - def insert(self: _T, loc: int, item) -> _T: """ Make new Index inserting new item at location. Follows diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 7ea43efbd91e1..40413bfb40b4b 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -822,19 +822,6 @@ def where(self, cond, other=None): result = IntervalArray(values) return type(self)._simple_new(result, name=self.name) - def delete(self, loc): - """ - Return a new IntervalIndex with passed location(-s) deleted - - Returns - ------- - IntervalIndex - """ - new_left = self.left.delete(loc) - new_right = self.right.delete(loc) - result = self._data._shallow_copy(new_left, new_right) - return type(self)._simple_new(result, name=self.name) - def insert(self, loc, item): """ Return a new IntervalIndex inserting new item at location. Follows diff --git a/pandas/tests/extension/base/methods.py b/pandas/tests/extension/base/methods.py index 3518f3b29e8c2..5906221389b35 100644 --- a/pandas/tests/extension/base/methods.py +++ b/pandas/tests/extension/base/methods.py @@ -491,6 +491,15 @@ def test_repeat_raises(self, data, repeats, kwargs, error, msg, use_numpy): else: data.repeat(repeats, **kwargs) + def test_delete(self, data): + result = data.delete(0) + expected = data[1:] + self.assert_extension_array_equal(result, expected) + + result = data.delete([1, 3]) + expected = data._concat_same_type([data[[0]], data[[2]], data[4:]]) + self.assert_extension_array_equal(result, expected) + @pytest.mark.parametrize("box", [pd.array, pd.Series, pd.DataFrame]) def test_equals(self, data, na_value, as_series, box): data2 = type(data)._from_sequence([data[0]] * len(data), dtype=data.dtype) From 033f8bbdcce7e44865f233aa5f1b6a82d1397c38 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 25 Jan 2021 15:12:09 -0800 Subject: [PATCH 3/3] mypy fixup --- pandas/core/arrays/base.py | 4 ++-- pandas/core/arrays/string_arrow.py | 2 +- pandas/core/indexes/extension.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 4aa5ab2f7b0d3..a62a5ec4ec7f7 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -997,12 +997,12 @@ def repeat(self, repeats, axis=None): # ------------------------------------------------------------------------ def take( - self, + self: ExtensionArrayT, indices: Sequence[int], *, allow_fill: bool = False, fill_value: Any = None, - ) -> ExtensionArray: + ) -> ExtensionArrayT: """ Take elements from an array. diff --git a/pandas/core/arrays/string_arrow.py b/pandas/core/arrays/string_arrow.py index cdca67237698b..252e9a84022db 100644 --- a/pandas/core/arrays/string_arrow.py +++ b/pandas/core/arrays/string_arrow.py @@ -507,7 +507,7 @@ def __setitem__(self, key: Union[int, np.ndarray], value: Any) -> None: def take( self, indices: Sequence[int], allow_fill: bool = False, fill_value: Any = None - ) -> ExtensionArray: + ): """ Take elements from an array. diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index 75f6658f94680..d17ac52e7cdd8 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -257,7 +257,7 @@ def searchsorted(self, value, side="left", sorter=None) -> np.ndarray: def _get_engine_target(self) -> np.ndarray: return np.asarray(self._data) - def delete(self: _T, loc) -> _T: + def delete(self, loc): """ Make new Index with passed location(-s) deleted