代码之家  ›  专栏  ›  技术社区  ›  eumiro

pandas.DatetimeIndex记得它是否关闭了吗?

  •  5
  • eumiro  · 技术社区  · 6 年前

    我有一个 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')
    

    end='2018-01-04' 又是属性?我需要它的数据库查询与时间戳范围。

    1. 根本没有 index.end
    2. index[-1] 退货 '2018-01-03'
    3. index[-1] + index.freq 在这种情况下有效,但对于 freq='2D'
    2 回复  |  直到 6 年前
        1
  •  5
  •   ivan_pozdeev RenanSS    6 年前

    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 it's an immutable type, so you need to override __new__ instead of __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 方法(包括类中继承的方法)现在将神奇地开始创建重写的类。 为此,需要在loaded中替换对基类的实时引用 这些方法使用的模块。 或者,您可以只替换原始的 __新建__ --那么就不需要替换引用了。

        2
  •  0
  •   wololo    6 年前

    像这样的东西对你有用吗?

    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')