From 0f4cde8f7d557ca4f0ce1cf08d2869e2ff216993 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 28 Jan 2020 11:39:09 -0800 Subject: [PATCH 1/2] CLN: update indexing now that Series._values matches Index._values --- pandas/core/base.py | 13 +++++-------- pandas/core/common.py | 10 ---------- pandas/core/frame.py | 8 ++------ pandas/core/indexes/base.py | 4 ---- pandas/core/series.py | 12 +++--------- pandas/tests/indexes/period/test_indexing.py | 6 ++++-- pandas/tests/series/indexing/test_indexing.py | 7 +++---- pandas/tests/series/indexing/test_numeric.py | 3 +-- 8 files changed, 18 insertions(+), 45 deletions(-) diff --git a/pandas/core/base.py b/pandas/core/base.py index 05e3302abddbe..46763a403df7c 100644 --- a/pandas/core/base.py +++ b/pandas/core/base.py @@ -1030,12 +1030,10 @@ def tolist(self): -------- numpy.ndarray.tolist """ - if self.dtype.kind in ["m", "M"]: - return [com.maybe_box_datetimelike(x) for x in self._values] - elif is_extension_array_dtype(self._values): + if not isinstance(self._values, np.ndarray): + # check for ndarray instead of dtype to catch DTA/TDA return list(self._values) - else: - return self._values.tolist() + return self._values.tolist() to_list = tolist @@ -1052,9 +1050,8 @@ def __iter__(self): iterator """ # We are explicitly making element iterators. - if self.dtype.kind in ["m", "M"]: - return map(com.maybe_box_datetimelike, self._values) - elif is_extension_array_dtype(self._values): + if not isinstance(self._values, np.ndarray): + # Check type instead of dtype to catch DTA/TDA return iter(self._values) else: return map(self._values.item, range(self._values.size)) diff --git a/pandas/core/common.py b/pandas/core/common.py index c883ec9fa49b7..9f307b68360f7 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -72,16 +72,6 @@ def consensus_name_attr(objs): return name -def maybe_box(indexer, values, obj, key): - - # if we have multiples coming back, box em - if isinstance(values, np.ndarray): - return obj[indexer.get_loc(key)] - - # return the value - return values - - def maybe_box_datetimelike(value): # turn a datetime like into a Timestamp/timedelta as needed diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f3a0cf3841b5b..e242d2153b23a 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2900,12 +2900,8 @@ def _get_value(self, index, col, takeable: bool = False): engine = self.index._engine try: - if isinstance(series._values, np.ndarray): - # i.e. not EA, we can use engine - return engine.get_value(series._values, index) - else: - loc = series.index.get_loc(index) - return series._values[loc] + loc = engine.get_loc(index) + return series._values[loc] except KeyError: # GH 20629 if self.index.nlevels > 1: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 10d9552e6f5a7..cb17b16cb60dc 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4669,10 +4669,6 @@ def _get_values_for_loc(self, series, loc): Assumes that `series.index is self` """ if is_integer(loc): - if isinstance(series._values, np.ndarray): - # Since we have an ndarray and not DatetimeArray, we dont - # have to worry about a tz. - return libindex.get_value_at(series._values, loc, tz=None) return series._values[loc] return series.iloc[loc] diff --git a/pandas/core/series.py b/pandas/core/series.py index 0aaa583885bc3..34f8e3a95993e 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -22,7 +22,7 @@ from pandas._config import get_option -from pandas._libs import index as libindex, lib, properties, reshape, tslibs +from pandas._libs import lib, properties, reshape, tslibs from pandas._typing import Label from pandas.compat.numpy import function as nv from pandas.util._decorators import Appender, Substitution @@ -838,13 +838,7 @@ def _ixs(self, i: int, axis: int = 0): ------- scalar (int) or Series (slice, sequence) """ - - # dispatch to the values if we need - values = self._values - if isinstance(values, np.ndarray): - return libindex.get_value_at(values, i) - else: - return values[i] + return self._values[i] def _slice(self, slobj: slice, axis: int = 0, kind=None) -> "Series": slobj = self.index._convert_slice_indexer(slobj, kind=kind or "getitem") @@ -975,7 +969,7 @@ def _get_value(self, label, takeable: bool = False): scalar value """ if takeable: - return com.maybe_box_datetimelike(self._values[label]) + return self._values[label] return self.index.get_value(self, label) def __setitem__(self, key, value): diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index 38514594efe09..fffc4a7562306 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -486,15 +486,17 @@ def test_get_value_datetime_hourly(self, freq): assert ser.loc[ts2] == 7 def test_get_value_integer(self): + msg = "index 16801 is out of bounds for axis 0 with size 3" dti = pd.date_range("2016-01-01", periods=3) pi = dti.to_period("D") ser = pd.Series(range(3), index=pi) - with pytest.raises(IndexError, match="index out of bounds"): + with pytest.raises(IndexError, match=msg): pi.get_value(ser, 16801) + msg = "index 46 is out of bounds for axis 0 with size 3" pi2 = dti.to_period("Y") # duplicates, ordinals are all 46 ser2 = pd.Series(range(3), index=pi2) - with pytest.raises(IndexError, match="index out of bounds"): + with pytest.raises(IndexError, match=msg): pi2.get_value(ser2, 46) def test_is_monotonic_increasing(self): diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index 65731cf45bd2d..52c26fa066223 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -17,10 +17,9 @@ def test_basic_indexing(): s = Series(np.random.randn(5), index=["a", "b", "a", "a", "b"]) - msg = "index out of bounds" + msg = "index 5 is out of bounds for axis 0 with size 5" with pytest.raises(IndexError, match=msg): s[5] - msg = "index 5 is out of bounds for axis 0 with size 5" with pytest.raises(IndexError, match=msg): s[5] = 0 @@ -29,7 +28,6 @@ def test_basic_indexing(): s = s.sort_index() - msg = r"index out of bounds|^5$" with pytest.raises(IndexError, match=msg): s[5] msg = r"index 5 is out of bounds for axis (0|1) with size 5|^5$" @@ -165,11 +163,12 @@ def test_getitem_with_duplicates_indices(result_1, duplicate_item, expected_1): def test_getitem_out_of_bounds(datetime_series): # don't segfault, GH #495 - msg = "index out of bounds" + msg = r"index \d+ is out of bounds for axis 0 with size \d+" with pytest.raises(IndexError, match=msg): datetime_series[len(datetime_series)] # GH #917 + msg = r"index -\d+ is out of bounds for axis 0 with size \d+" s = Series([], dtype=object) with pytest.raises(IndexError, match=msg): s[-1] diff --git a/pandas/tests/series/indexing/test_numeric.py b/pandas/tests/series/indexing/test_numeric.py index 3684ca00c2f17..771f5533f29d8 100644 --- a/pandas/tests/series/indexing/test_numeric.py +++ b/pandas/tests/series/indexing/test_numeric.py @@ -202,10 +202,9 @@ def test_slice_float64(): def test_getitem_negative_out_of_bounds(): s = Series(tm.rands_array(5, 10), index=tm.rands_array(10, 10)) - msg = "index out of bounds" + msg = "index -11 is out of bounds for axis 0 with size 10" with pytest.raises(IndexError, match=msg): s[-11] - msg = "index -11 is out of bounds for axis 0 with size 10" with pytest.raises(IndexError, match=msg): s[-11] = "foo" From 2a2dc015db30778d32b8535b05b9fb5aad471e5b Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Jan 2020 11:45:01 -0800 Subject: [PATCH 2/2] revert --- pandas/core/common.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pandas/core/common.py b/pandas/core/common.py index 9f307b68360f7..c883ec9fa49b7 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -72,6 +72,16 @@ def consensus_name_attr(objs): return name +def maybe_box(indexer, values, obj, key): + + # if we have multiples coming back, box em + if isinstance(values, np.ndarray): + return obj[indexer.get_loc(key)] + + # return the value + return values + + def maybe_box_datetimelike(value): # turn a datetime like into a Timestamp/timedelta as needed