Может ли pandas.DatetimeIndex запомнить, закрыт ли он? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть pandas.DatetimeIndex для интервала ['2018-01-01', '2018-01-04') (начало включено, конец исключен) и freq=1D:

>>> index = pd.DatetimeIndex(start='2018-01-01',
                             end='2018-01-04',
                             freq='1D',
                             closed='left')
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03'],
              dtype='datetime64[ns]',
              freq='D')

Как я могу снова получить правильный атрибут open end='2018-01-04'?Мне это нужно для запроса к БД с диапазонами отметок времени.

  1. Нет index.end
  2. index[-1] возвращает '2018-01-03'
  3. index[-1] + index.freq работает вэтот случай, но это неправильно для freq='2D'

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Может ли что-то подобное для вас работать?

index = pd.DatetimeIndex(start='2018-01-01', end='2018-01-04',  freq='1D', closed='left')

def get_end(index, freq):
    if freq == '1D':
        return(index.max()+1)

get_end(index, '1D')

Вы можете написать логику для 1D / 2D / 1M.Кроме того, сделайте имя столбца dateIndex с параметром Freq в качестве суффикса / префикса 'purchase_date_1D' и проанализируйте его, если вы даже не хотите предоставлять его в качестве отдельного ввода.

0 голосов
/ 11 октября 2018

Нет способа, потому что эта информация теряется после создания объекта.Во время создания интервал развертывается в результирующую последовательность:

pandas/core/indexes/datetimes.py:

class DatetimeIndex(<...>):

    <...>

    @classmethod
    def _generate(cls, start, end, periods, name, freq,
                  tz=None, normalize=False, ambiguous='raise', closed=None):
        <...>

                index = tools.to_datetime(np.linspace(start.value,
                                                      end.value, periods),
                                          utc=True)
                <...>

        if not left_closed and len(index) and index[0] == start:
            index = index[1:]
        if not right_closed and len(index) and index[-1] == end:
            index = index[:-1]
        index = cls._simple_new(index, name=name, freq=freq, tz=tz)
        return index

Ни одна информация closed нигде не сохранена, поэтому вы даже не можете вывести ее изпервая / последняя точка и шаг.


Вы можете создать подкласс DatetimeIndex и сохранить эту информацию.Обратите внимание, что это неизменный тип, поэтому вам нужно переопределить __new__ вместо __init__:

import inspect, collections
class SiDatetimeIndex(pd.DatetimeIndex):

    _Interval = collections.namedtuple('Interval',
            ('start','end','freq','closed'))
    #add 'interval' to dir(): DatetimeIndex inherits pandas.core.accessor.DirNamesMixin
    _accessors = pd.DatetimeIndex._accessors | frozenset(('interval',))

    def __new__(cls, *args, **kwargs):
        base_new = super(SiDatetimeIndex,cls).__new__
        callargs = inspect.getcallargs(base_new,cls,*args,**kwargs)
        result = base_new(**callargs)
        result.interval = cls._Interval._make(callargs[a] for a in cls._Interval._fields)
        return result


In [31]: index = SiDatetimeIndex(start='2018-01-01',
...:                              end='2018-01-04',
...:                              freq='1D',
...:                              closed='left')

In [38]: index.interval
Out[38]: Interval(start='2018-01-01', end='2018-01-04', freq='1D', closed='left')

Не ожидайте, что все методы pandas (включаяунаследованные в вашем классе) теперь волшебным образом начнут создавать переопределенный класс.Для этого вам необходимо заменить действующие ссылки на базовый класс в загруженных pandas модулях, которые используют эти методы.Кроме того, вы можете заменить только оригинал __new__ - тогда нет необходимости заменять ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...