From 824ddbeb5a27f3715371eb7d90b54d01eea5e629 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Tue, 26 Jan 2016 17:00:09 -0500 Subject: [PATCH] BUG: getitem and a series with a non-ndarray values closes #12089 --- doc/source/whatsnew/v0.18.0.txt | 2 +- pandas/index.pyx | 4 ++-- pandas/indexes/base.py | 10 +++++++-- pandas/tests/series/test_indexing.py | 32 ++++++++++++++++++++++++++++ pandas/tseries/index.py | 3 ++- 5 files changed, 45 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index ccdc48bc1dbbb..56e5b75bb0a27 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -483,7 +483,7 @@ Bug Fixes - Compat for numpy 1.11 w.r.t. ``NaT`` comparison changes (:issue:`12049`) - Bug in ``read_csv`` when reading from a ``StringIO`` in threads (:issue:`11790`) - Bug in not treating ``NaT`` as a missing value in datetimelikes when factorizing & with ``Categoricals`` (:issue:`12077`) - +- Bug in getitem when the values of a ``Series`` were tz-aware (:issue:`12089`) diff --git a/pandas/index.pyx b/pandas/index.pyx index 1678e3b280ee5..a7e613ee867c7 100644 --- a/pandas/index.pyx +++ b/pandas/index.pyx @@ -100,7 +100,7 @@ cdef class IndexEngine: hash(val) return val in self.mapping - cpdef get_value(self, ndarray arr, object key): + cpdef get_value(self, ndarray arr, object key, object tz=None): ''' arr : 1-dimensional ndarray ''' @@ -113,7 +113,7 @@ cdef class IndexEngine: return arr[loc] else: if arr.descr.type_num == NPY_DATETIME: - return Timestamp(util.get_value_at(arr, loc)) + return Timestamp(util.get_value_at(arr, loc), tz=tz) elif arr.descr.type_num == NPY_TIMEDELTA: return Timedelta(util.get_value_at(arr, loc)) return util.get_value_at(arr, loc) diff --git a/pandas/indexes/base.py b/pandas/indexes/base.py index 0147000e4380c..9064b77ef7e3d 100644 --- a/pandas/indexes/base.py +++ b/pandas/indexes/base.py @@ -1881,7 +1881,12 @@ def get_value(self, series, key): # use this, e.g. DatetimeIndex s = getattr(series, '_values', None) if isinstance(s, Index) and lib.isscalar(key): - return s[key] + try: + return s[key] + except (IndexError, ValueError): + + # invalid type as an indexer + pass s = _values_from_object(series) k = _values_from_object(key) @@ -1891,7 +1896,8 @@ def get_value(self, series, key): raise KeyError try: - return self._engine.get_value(s, k) + return self._engine.get_value(s, k, + tz=getattr(series.dtype, 'tz', None)) except KeyError as e1: if len(self) > 0 and self.inferred_type in ['integer', 'boolean']: raise diff --git a/pandas/tests/series/test_indexing.py b/pandas/tests/series/test_indexing.py index 537c2d07443e4..c5ebbca67dc0e 100644 --- a/pandas/tests/series/test_indexing.py +++ b/pandas/tests/series/test_indexing.py @@ -613,6 +613,18 @@ def test_basic_getitem_with_labels(self): expected = s.reindex(arr_inds) assert_series_equal(result, expected) + # GH12089 + # with tz for values + s = Series(pd.date_range("2011-01-01", periods=3, tz="US/Eastern"), + index=['a', 'b', 'c']) + expected = Timestamp('2011-01-01', tz='US/Eastern') + result = s.loc['a'] + self.assertEqual(result, expected) + result = s.iloc[0] + self.assertEqual(result, expected) + result = s['a'] + self.assertEqual(result, expected) + def test_basic_setitem_with_labels(self): indices = self.ts.index[[5, 10, 15]] @@ -650,6 +662,26 @@ def test_basic_setitem_with_labels(self): self.assertRaises(Exception, s.__setitem__, inds_notfound, 0) self.assertRaises(Exception, s.__setitem__, arr_inds_notfound, 0) + # GH12089 + # with tz for values + s = Series(pd.date_range("2011-01-01", periods=3, tz="US/Eastern"), + index=['a', 'b', 'c']) + s2 = s.copy() + expected = Timestamp('2011-01-03', tz='US/Eastern') + s2.loc['a'] = expected + result = s2.loc['a'] + self.assertEqual(result, expected) + + s2 = s.copy() + s2.iloc[0] = expected + result = s2.iloc[0] + self.assertEqual(result, expected) + + s2 = s.copy() + s2['a'] = expected + result = s2['a'] + self.assertEqual(result, expected) + def test_ix_getitem(self): inds = self.series.index[[3, 4, 7]] assert_series_equal(self.series.ix[inds], self.series.reindex(inds)) diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index bb4f878157595..4d5f64bc95249 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -1361,7 +1361,8 @@ def get_value_maybe_box(self, series, key): key = Timestamp(key, tz=self.tz) elif not isinstance(key, Timestamp): key = Timestamp(key) - values = self._engine.get_value(_values_from_object(series), key) + values = self._engine.get_value(_values_from_object(series), + key, tz=self.tz) return _maybe_box(self, values, series, key) def get_loc(self, key, method=None, tolerance=None):