diff --git a/RELEASE.rst b/RELEASE.rst index a1bb3a252ec6e..65411b9b69cad 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -203,6 +203,8 @@ pandas 0.11.0 - series.plot(kind='bar') now respects pylab color schem (GH3115_) - Fixed bug in reshape if not passed correct input, now raises TypeError (GH2719_) - Fix NameError issue on RESO_US (GH2787_) + - Allow selection in an *unordered* timeseries to work similary + to an *ordered* timeseries (GH2437_). .. _GH2758: https://github.com/pydata/pandas/issues/2758 .. _GH2809: https://github.com/pydata/pandas/issues/2809 @@ -229,6 +231,7 @@ pandas 0.11.0 .. _GH2776: https://github.com/pydata/pandas/issues/2776 .. _GH2778: https://github.com/pydata/pandas/issues/2778 .. _GH2787: https://github.com/pydata/pandas/issues/2787 +.. _GH2437: https://github.com/pydata/pandas/issues/2437 .. _GH2793: https://github.com/pydata/pandas/issues/2793 .. _GH2795: https://github.com/pydata/pandas/issues/2795 .. _GH2819: https://github.com/pydata/pandas/issues/2819 diff --git a/doc/source/v0.11.0.txt b/doc/source/v0.11.0.txt index eba37c02c6237..f13fb50f1aa3c 100644 --- a/doc/source/v0.11.0.txt +++ b/doc/source/v0.11.0.txt @@ -243,6 +243,8 @@ Enhancements - In ``HDFStore``, new keywords ``iterator=boolean``, and ``chunksize=number_in_a_chunk`` are provided to support iteration on ``select`` and ``select_as_multiple`` (GH3076_) + - You can now select timestamps from an *unordered* timeseries similarly to an *ordered* timeseries (GH2437_) + - ``Squeeze`` to possibly remove length 1 dimensions from an object. .. ipython:: python @@ -293,6 +295,7 @@ See the `full release notes `__ or issue tracker on GitHub for a complete list. +.. _GH2437: https://github.com/pydata/pandas/issues/2437 .. _GH2809: https://github.com/pydata/pandas/issues/2809 .. _GH2810: https://github.com/pydata/pandas/issues/2810 .. _GH2837: https://github.com/pydata/pandas/issues/2837 diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index c91a1ebd5568f..25c94900d159c 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -1042,9 +1042,6 @@ def intersection(self, other): return self._view_like(left_chunk) def _partial_date_slice(self, reso, parsed): - if not self.is_monotonic: - raise TimeSeriesError('Partial indexing only valid for ordered ' - 'time series.') if reso == 'year': t1 = Timestamp(datetime(parsed.year, 1, 1), tz=self.tz) @@ -1079,11 +1076,19 @@ def _partial_date_slice(self, reso, parsed): tz=self.tz).value - 1) else: raise KeyError + stamps = self.asi8 - left = stamps.searchsorted(t1.value, side='left') - right = stamps.searchsorted(t2.value, side='right') - return slice(left, right) + + if self.is_monotonic: + + # a monotonic (sorted) series can be sliced + left = stamps.searchsorted(t1.value, side='left') + right = stamps.searchsorted(t2.value, side='right') + return slice(left, right) + + # try to find a the dates + return ((stamps>=t1.value) & (stamps<=t2.value)).nonzero()[0] def _possibly_promote(self, other): if other.inferred_type == 'date': diff --git a/pandas/tseries/tests/test_timeseries.py b/pandas/tseries/tests/test_timeseries.py index 2ec4fd7ffd67b..6155590100452 100644 --- a/pandas/tseries/tests/test_timeseries.py +++ b/pandas/tseries/tests/test_timeseries.py @@ -18,6 +18,7 @@ import pandas.core.datetools as datetools import pandas.tseries.offsets as offsets import pandas.tseries.frequencies as fmod +from pandas.tseries.index import TimeSeriesError import pandas as pd from pandas.util.testing import assert_series_equal, assert_almost_equal @@ -168,6 +169,32 @@ def test_indexing_over_size_cutoff(self): finally: _index._SIZE_CUTOFF = old_cutoff + def test_indexing_unordered(self): + + # GH 2437 + from pandas import concat + rng = date_range(start='2011-01-01', end='2011-01-15') + ts = Series(randn(len(rng)), index=rng) + ts2 = concat([ts[0:4],ts[-4:],ts[4:-4]]) + + for t in ts.index: + s = str(t) + expected = ts[t] + result = ts2[t] + self.assertTrue(expected == result) + + result = ts2['2011'].sort_index() + expected = ts['2011'] + assert_series_equal(result,expected) + + # diff freq + rng = date_range(datetime(2005, 1, 1), periods=20, freq='M') + ts = Series(np.arange(len(rng)), index=rng) + ts = ts.take(np.random.permutation(20)) + + result = ts['2005'] + for t in result.index: + self.assertTrue(t.year == 2005) def assert_range_equal(left, right): assert(left.equals(right)) @@ -2017,13 +2044,6 @@ def test_partial_slice_minutely(self): self.assert_(s['2005-1-1 23:59:00'] == s.ix[0]) self.assertRaises(Exception, s.__getitem__, '2004-12-31 00:00:00') - def test_partial_not_monotonic(self): - rng = date_range(datetime(2005, 1, 1), periods=20, freq='M') - ts = Series(np.arange(len(rng)), index=rng) - ts = ts.take(np.random.permutation(20)) - - self.assertRaises(Exception, ts.__getitem__, '2005') - def test_date_range_normalize(self): snap = datetime.today() n = 50