B
    W0d/                 @  s   d Z ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 ddlmZ ddlmZ d	ZG d
d dZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZdS )zLIndexer objects for computing start/end window bounds for rolling operations    )annotations)	timedeltaN) calculate_variable_window_bounds)Appender)ensure_platform_int)Nanoa\  
Computes the bounds of a window.

Parameters
----------
num_values : int, default 0
    number of values that will be aggregated over
window_size : int, default 0
    the number of rows in a window
min_periods : int, default None
    min_periods passed from the top level rolling API
center : bool, default None
    center passed from the top level rolling API
closed : str, default None
    closed passed from the top level rolling API
win_type : str, default None
    win_type passed from the top level rolling API

Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
c               @  sB   e Zd ZdZddddddZeeddd	d
dddddZdS )BaseIndexerz*Base class for window bounds calculations.Nr   znp.ndarray | Noneint)index_arraywindow_sizec             K  s2   || _ || _x | D ]\}}t| || qW dS )z
        Parameters
        ----------
        **kwargs :
            keyword arguments that will be available when get_window_bounds is called
        N)r
   r   itemssetattr)selfr
   r   kwargskeyvalue r   M/var/www/html/venv/lib/python3.7/site-packages/pandas/core/window/indexers.py__init__+   s    	zBaseIndexer.__init__z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])
num_valuesmin_periodscenterclosedreturnc             C  s   t d S )N)NotImplementedError)r   r   r   r   r   r   r   r   get_window_bounds:   s    	zBaseIndexer.get_window_bounds)Nr   )r   NNN)__name__
__module____qualname____doc__r   r   get_window_bounds_docr   r   r   r   r   r   (   s      r   c               @  s0   e Zd ZdZeeddddddd	d
dZdS )FixedWindowIndexerz3Creates window boundaries that are of fixed length.r   Nr	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s   |r| j d d }nd}tjd| |d | dd}|| j  }|dkrN|d8 }|dkr^|d8 }t|d|}t|d|}||fS )N      r   int64)dtype)leftboth)r&   Zneither)r   nparangeZclip)r   r   r   r   r   offsetendstartr   r   r   r   I   s    	
z$FixedWindowIndexer.get_window_bounds)r   NNN)r   r   r   r   r   r    r   r   r   r   r   r!   F   s      r!   c               @  s0   e Zd ZdZeeddddddd	d
dZdS )VariableWindowIndexerzNCreates window boundaries that are of variable length, namely for time series.r   Nr	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s   t || j|||| jS )N)r   r   r
   )r   r   r   r   r   r   r   r   r   g   s    z'VariableWindowIndexer.get_window_bounds)r   NNN)r   r   r   r   r   r    r   r   r   r   r   r-   d   s      r-   c                  sJ   e Zd ZdZdddd fddZeeddd	d
dddddZ  ZS )VariableOffsetWindowIndexerzMCalculate window boundaries based on a non-fixed offset such as a BusinessDayNr   znp.ndarray | Noner	   )r
   r   c               s"   t  j||f| || _|| _d S )N)superr   indexr*   )r   r
   r   r0   r*   r   )	__class__r   r   r      s    z$VariableOffsetWindowIndexer.__init__z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s  |d kr| j d k	rdnd}|dk}|dk}| j |d  | j d k rHd}nd}tj|dd	}|d tj|dd	}	|	d d|d< |rd|	d< nd|	d< xtd|D ]}
| j |
 }| j |
 || j  }|r|td8 }|
||
< x>t||
d  |
D ](}| j | | | tdkr|||
< P qW | j |	|
d   | | tdkrR|
d |	|
< n|	|
d  |	|
< |s|	|
  d8  < qW ||	fS )
Nrightr'   )r2   r'   )r&   r'   r"   r   r$   )r%   )r0   r(   emptyfillranger*   r   r   )r   r   r   r   r   Zright_closedZleft_closedZindex_growth_signr,   r+   iZ	end_boundZstart_boundjr   r   r   r      s>    




$z-VariableOffsetWindowIndexer.get_window_bounds)Nr   NN)r   NNN)	r   r   r   r   r   r   r    r   __classcell__r   r   )r1   r   r.   ~   s         r.   c               @  s0   e Zd ZdZeeddddddd	d
dZdS )ExpandingIndexerz;Calculate expanding window bounds, mimicking df.expanding()r   Nr	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s&   t j|t jdt jd|d t jdfS )N)r%   r"   )r(   Zzerosr$   r)   )r   r   r   r   r   r   r   r   r      s    
z"ExpandingIndexer.get_window_bounds)r   NNN)r   r   r   r   r   r    r   r   r   r   r   r:      s      r:   c               @  s0   e Zd ZdZeeddddddd	d
dZdS )FixedForwardWindowIndexera  
    Creates window boundaries for fixed-length windows that include the
    current row.

    Examples
    --------
    >>> df = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]})
    >>> df
         B
    0  0.0
    1  1.0
    2  2.0
    3  NaN
    4  4.0

    >>> indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=2)
    >>> df.rolling(window=indexer, min_periods=1).sum()
         B
    0  1.0
    1  3.0
    2  2.0
    3  4.0
    4  4.0
    r   Nr	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  sR   |rt d|d k	rt dtj|dd}|| j }| jrJ||| j d < ||fS )Nz.Forward-looking windows can't have center=TruezAForward-looking windows don't support setting the closed argumentr$   )r%   )
ValueErrorr(   r)   r   )r   r   r   r   r   r,   r+   r   r   r   r      s    	
z+FixedForwardWindowIndexer.get_window_bounds)r   NNN)r   r   r   r   r   r    r   r   r   r   r   r;      s      r;   c                  sZ   e Zd ZdZdddedfdddddd fd	d
ZeedddddddddZ  Z	S )GroupbyIndexerzMCalculate bounds to compute groupby rolling, mimicking df.groupby().rolling()Nr   znp.ndarray | Nonezint | BaseIndexerzdict | Noneztype[BaseIndexer])r
   r   groupby_indiceswindow_indexerindexer_kwargsc               sH   |pi | _ || _|r| ni | _t jf || jd|d| dS )a4  
        Parameters
        ----------
        index_array : np.ndarray or None
            np.ndarray of the index of the original object that we are performing
            a chained groupby operation over. This index has been pre-sorted relative to
            the groups
        window_size : int or BaseIndexer
            window size during the windowing operation
        groupby_indices : dict or None
            dict of {group label: [positional index of rows belonging to the group]}
        window_indexer : BaseIndexer
            BaseIndexer class determining the start and end bounds of each group
        indexer_kwargs : dict or None
            Custom kwargs to be passed to window_indexer
        **kwargs :
            keyword arguments that will be available when get_window_bounds is called
        r   )r
   r   N)r>   r?   copyr@   r/   r   pop)r   r
   r   r>   r?   r@   r   )r1   r   r   r     s    
zGroupbyIndexer.__init__r	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s0  g }g }d}x| j  D ]\}}	| jd k	r>| jt|	}
n| j}
| jf |
| jd| j}|t	|	|||\}}|
tj}|
tj}t	|t	|kstdt||t	|	 }|t	|	7 }t||d d gj
tjdd}||t| ||t| qW t|}t|}||fS )Nr   )r
   r   z6these should be equal in length from get_window_boundsr3   r"   F)rA   )r>   r   r
   Ztaker   r?   r   r@   r   lenZastyper(   r$   AssertionErrorr)   appendZconcatenate)r   r   r   r   r   Zstart_arraysZ
end_arraysZwindow_indices_startr   indicesr
   Zindexerr,   r+   Zwindow_indicesr   r   r   r   ;  s8    




z GroupbyIndexer.get_window_bounds)r   NNN)
r   r   r   r   r   r   r   r    r   r9   r   r   )r1   r   r=     s      r=   c               @  s0   e Zd ZdZeeddddddd	d
dZdS )ExponentialMovingWindowIndexerz/Calculate ewm window bounds (the entire window)r   Nr	   z
int | Nonezbool | Nonez
str | Noneztuple[np.ndarray, np.ndarray])r   r   r   r   r   c             C  s$   t jdgt jdt j|gt jdfS )Nr   )r%   )r(   arrayr$   )r   r   r   r   r   r   r   r   r   q  s    	z0ExponentialMovingWindowIndexer.get_window_bounds)r   NNN)r   r   r   r   r   r    r   r   r   r   r   rG   n  s      rG   )r   
__future__r   datetimer   numpyr(   Zpandas._libs.window.indexersr   Zpandas.util._decoratorsr   Zpandas.core.dtypes.commonr   Zpandas.tseries.offsetsr   r    r   r!   r-   r.   r:   r;   r=   rG   r   r   r   r   <module>   s    R2Z