o
    5c$2                     @  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
step : int, default None
    step passed from the top level rolling API
    .. versionadded:: 1.5
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                   @  s<   e Zd ZdZ	ddd
dZee					ddddZdS )BaseIndexerz*Base class for window bounds calculations.Nr   index_arraynp.ndarray | Nonewindow_sizeintreturnNonec                 K  s.   || _ || _| D ]
\}}t| || q
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   R/var/www/html/gps/gps/lib/python3.10/site-packages/pandas/core/indexers/objects.py__init__.   s
   	zBaseIndexer.__init__
num_valuesmin_periods
int | Nonecenterbool | Noneclosed
str | Nonesteptuple[np.ndarray, np.ndarray]c                 C  s   t N)NotImplementedErrorr   r   r   r   r   r   r   r   r   get_window_bounds=   s   
zBaseIndexer.get_window_bounds)Nr   r	   r
   r   r   r   r   r   NNNNr   r   r   r   r   r   r   r   r   r   r   r    )__name__
__module____qualname____doc__r   r   get_window_bounds_docr$   r   r   r   r   r   +   s    r   c                   @  .   e Zd ZdZee					ddddZdS )FixedWindowIndexerz3Creates window boundaries that are of fixed length.r   Nr   r   r   r   r   r   r   r   r   r   r    c           	      C  s   |r
| j d d }nd}tjd| |d | |dd}|| j  }|dv r(|d8 }|dv r0|d8 }t|d|}t|d|}||fS )N      r   int64dtypeleftboth)r5   neither)r   nparangeclip)	r   r   r   r   r   r   offsetendstartr   r   r   r$   M   s   

z$FixedWindowIndexer.get_window_boundsr&   r'   r(   r)   r*   r+   r   r,   r$   r   r   r   r   r.   J       r.   c                   @  r-   )VariableWindowIndexerzNCreates window boundaries that are of variable length, namely for time series.r   Nr   r   r   r   r   r   r   r   r   r   r    c                 C  s   t || j|||| jS r!   )r   r   r	   r#   r   r   r   r$   l   s   z'VariableWindowIndexer.get_window_boundsr&   r'   r>   r   r   r   r   r@   i   r?   r@   c                      sJ   e Zd ZdZ				dd fd
dZee					ddddZ  ZS )VariableOffsetWindowIndexerzNCalculate window boundaries based on a non-fixed offset such as a BusinessDay.Nr   r	   r
   r   r   r   r   c                   s&   t  j||fi | || _|| _d S r!   )superr   indexr;   )r   r	   r   rC   r;   r   	__class__r   r   r      s   
z$VariableOffsetWindowIndexer.__init__r   r   r   r   r   r   r   r   r    c                 C  s  |d urt d|dkrtjdddtjdddfS |d u r'| jd ur%dnd}|dv }|dv }| j|d	  | jd k r>d
}nd	}tj|dd}	|	d
 tj|dd}
|
d
 d|	d< |rcd	|
d< nd|
d< td	|D ]f}| j| }| j| || j  }|r|td	8 }||	|< t|	|d	  |D ]}| j| | | tdkr||	|<  nq| j|
|d	   | | tdkr|d	 |
|< n|
|d	  |
|< |s|
|  d	8  < ql|	|
fS )Nz/step not implemented for variable offset windowr   r1   r2   rightr6   )rF   r6   r4   r/   )	r"   r8   emptyrC   fillranger;   r   r   )r   r   r   r   r   r   right_closedleft_closedindex_growth_signr=   r<   i	end_boundstart_boundjr   r   r   r$      sJ   




"z-VariableOffsetWindowIndexer.get_window_bounds)Nr   NNr%   r&   r'   )	r(   r)   r*   r+   r   r   r,   r$   __classcell__r   r   rD   r   rA      s    rA   c                   @  r-   )ExpandingIndexerz;Calculate expanding window bounds, mimicking df.expanding()r   Nr   r   r   r   r   r   r   r   r   r   r    c                 C  s&   t j|t jdt jd|d t jdfS )Nr2   r/   )r8   zerosr1   r9   r#   r   r   r   r$      s   z"ExpandingIndexer.get_window_boundsr&   r'   r>   r   r   r   r   rS      r?   rS   c                   @  r-   )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   r   r   r   r   r   r   r   r   r   r    c                 C  s`   |rt d|d urt d|d u rd}tjd||dd}|| j }| jr,t|d|}||fS )Nz.Forward-looking windows can't have center=TruezAForward-looking windows don't support setting the closed argumentr/   r   r1   r2   )
ValueErrorr8   r9   r   r:   )r   r   r   r   r   r   r=   r<   r   r   r   r$     s   

z+FixedForwardWindowIndexer.get_window_boundsr&   r'   r>   r   r   r   r   rU      s    rU   c                      sL   e Zd ZdZdddedfd fddZee					ddddZ  Z	S ) GroupbyIndexerzMCalculate bounds to compute groupby rolling, mimicking df.groupby().rolling()Nr   r	   r
   r   int | BaseIndexergroupby_indicesdict | Nonewindow_indexertype[BaseIndexer]indexer_kwargsr   r   c                   sH   |pi | _ || _|r| ni | _t jd|| 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   Nr   )rY   r[   copyr]   rB   r   pop)r   r	   r   rY   r[   r]   r   rD   r   r   r   &  s   

zGroupbyIndexer.__init__r   r   r   r   r   r   r   r   r   r    c                 C  sX  g }g }d}| j  D ]|\}	}
| jd ur| jt|
}n| j}| jd	|| jd| j}|t	|
||||\}}|
tj}|
tj}t	|t	|ksRJ dt||t	|
 }|t	|
7 }t||d d gj
tjdd}||t| ||t| qt	|dkrtjg tjdtjg tjdfS t|}t|}||fS )
Nr   r^   z6these should be equal in length from get_window_boundsrG   r/   F)r_   r2   r   )rY   r   r	   taker   r[   r   r]   r$   lenastyper8   r1   r9   appendarrayconcatenate)r   r   r   r   r   r   start_arrays
end_arrayswindow_indices_startr   indicesr	   indexerr=   r<   window_indicesr   r   r   r$   J  sJ   
 

z GroupbyIndexer.get_window_bounds)r	   r
   r   rX   rY   rZ   r[   r\   r]   rZ   r   r   r&   r'   )
r(   r)   r*   r+   r   r   r   r,   r$   rR   r   r   rD   r   rW   #  s    $rW   c                   @  r-   )ExponentialMovingWindowIndexerz/Calculate ewm window bounds (the entire window)r   Nr   r   r   r   r   r   r   r   r   r   r    c                 C  s$   t jdgt jdt j|gt jdfS )Nr   r2   )r8   re   r1   r#   r   r   r   r$     s   $
z0ExponentialMovingWindowIndexer.get_window_boundsr&   r'   r>   r   r   r   r   rm     r?   rm   )r+   
__future__r   datetimer   numpyr8   pandas._libs.window.indexersr   pandas.util._decoratorsr   pandas.core.dtypes.commonr   pandas.tseries.offsetsr   r,   r   r.   r@   rA   rS   rU   rW   rm   r   r   r   r   <module>   s"    X4^