From ddef9d99cc0ae7ba51bc26788fed34c4462babba Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 31 Jan 2020 16:10:16 -0600 Subject: [PATCH 1/2] REGR: Fixed slicing DatetimeIndex with date Closes https://github.com/pandas-dev/pandas/issues/31501 --- doc/source/whatsnew/v1.0.1.rst | 2 +- pandas/core/indexes/datetimes.py | 9 ++++++++- pandas/tests/indexing/test_datetime.py | 22 +++++++++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v1.0.1.rst b/doc/source/whatsnew/v1.0.1.rst index ff8433c7cafd9..22aea85ad610e 100644 --- a/doc/source/whatsnew/v1.0.1.rst +++ b/doc/source/whatsnew/v1.0.1.rst @@ -68,7 +68,7 @@ Interval Indexing ^^^^^^^^ -- +- Fixed regression when indexing a ``Series`` or ``DataFrame`` indexed by ``DatetimeIndex`` with a slice containg a :class:`datetime.date` (:issue:`31501`) - Missing diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 2b4636155111f..4b7a36f07454e 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -1,4 +1,4 @@ -from datetime import datetime, time, timedelta, tzinfo +from datetime import date, datetime, time, timedelta, tzinfo import operator from typing import Optional import warnings @@ -758,6 +758,13 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None): if isinstance(start, time) or isinstance(end, time): raise KeyError("Cannot mix time and non-time slice keys") + # Pandas supports slicing with dates, treated as datetimes at midnight. + # https://github.com/pandas-dev/pandas/issues/31501 + if isinstance(start, date): + start = datetime.combine(start, time(0, 0)) + if isinstance(end, date): + end = datetime.combine(end, time(0, 0)) + try: return Index.slice_indexer(self, start, end, step, kind=kind) except KeyError: diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py index 42f992339f036..c8c2d1ed587cf 100644 --- a/pandas/tests/indexing/test_datetime.py +++ b/pandas/tests/indexing/test_datetime.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta +from datetime import date, datetime, timedelta from dateutil import tz import numpy as np @@ -350,3 +350,23 @@ def test_loc_label_slicing(self): expected = ser.iloc[:-1] tm.assert_series_equal(result, expected) + + @pytest.mark.parametrize( + "slice_, positions", + [ + [slice(date(2018, 1, 1), None), [0, 1, 2]], + [slice(date(2019, 1, 2), None), [2]], + [slice(date(2020, 1, 1), None), []], + [slice(None, date(2020, 1, 1)), [0, 1, 2]], + [slice(None, date(2019, 1, 1)), [0]], + ], + ) + def test_getitem_slice_date(self, slice_, positions): + # https://github.com/pandas-dev/pandas/issues/31501 + s = pd.Series( + [0, 1, 2], + pd.DatetimeIndex(["2019-01-01", "2019-01-01T06:00:00", "2019-01-02"]), + ) + result = s[slice_] + expected = s.take(positions) + tm.assert_series_equal(result, expected) From f61fc8c3c94e60766682791a11e5ce86cad9cf5f Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Fri, 31 Jan 2020 16:36:48 -0600 Subject: [PATCH 2/2] fixup --- pandas/core/indexes/datetimes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 4b7a36f07454e..416c3d0701a85 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -760,9 +760,9 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None): # Pandas supports slicing with dates, treated as datetimes at midnight. # https://github.com/pandas-dev/pandas/issues/31501 - if isinstance(start, date): + if isinstance(start, date) and not isinstance(start, datetime): start = datetime.combine(start, time(0, 0)) - if isinstance(end, date): + if isinstance(end, date) and not isinstance(end, datetime): end = datetime.combine(end, time(0, 0)) try: