How to slice a pandas.DatetimeIndex?

Viewed 4068

What is the best way to get dates between, say, '2019-01-08' and '2019-01-16', from the pandas.DatetimeIndex object dti as constructed below? Ideally, some concise syntax like dti['2019-01-08':'2019-01-16']?

import pandas as pd
dti = pd.bdate_range(start='2019-01-01', end='2019-02-15')

DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04',
               '2019-01-07', '2019-01-08', '2019-01-09', '2019-01-10',
               '2019-01-11', '2019-01-14', '2019-01-15', '2019-01-16',
               '2019-01-17', '2019-01-18', '2019-01-21', '2019-01-22',
               '2019-01-23', '2019-01-24', '2019-01-25', '2019-01-28',
               '2019-01-29', '2019-01-30', '2019-01-31', '2019-02-01',
               '2019-02-04', '2019-02-05', '2019-02-06', '2019-02-07',
               '2019-02-08', '2019-02-11', '2019-02-12', '2019-02-13',
               '2019-02-14', '2019-02-15'],
              dtype='datetime64[ns]', freq='B')
2 Answers

You can do it with the slice_indexer for DateTimeIndex

pandas.DateTimeIndex.slice_indexer(start, stop, step, [...])

It returns the indexes of the datetime items so you can pass it to dti

Example:

dti[dti.slice_indexer("2019-01-07", "2019-01-17")]

If you read the source code for DatetimeIndex.__getitem__ method, the individual dates in a DatetimeIndex is stored in a DatetimeArray. To support slicing, you need to get the integer indices of the start and stop date in that array. I suggest that you file a feature request with the pandas development team.

Meanwhile, you can monkey-patch it in:

from pandas.core.indexes.datetimes import DatetimeIndex

__old_getitem = DatetimeIndex.__getitem__

def __new_getitem(index, key):
    if isinstance(key, slice):
        _key = index.slice_indexer(key.start, key.stop, key.step)
    else:
        _key = key

    return __old_getitem(index, _key)

DatetimeIndex.__getitem__ = __new_getitem

# Now you can slice
dti['2019-01-08':'2019-01-16':4]
Related