§
    	�’j^  ã                  ó¶  — 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d	lmZ dd
lmZ  ed¦  «         G d„ d¦  «        ¦   «         Z G d„ de¦  «        Z G d„ de¦  «        Z ed¦  «         G d„ de¦  «        ¦   «         Z G d„ de¦  «        Z ed¦  «         G d„ de¦  «        ¦   «         Z G d„ de¦  «        Z G d„ de¦  «        ZdS )zLIndexer objects for computing start/end window bounds for rolling operationsé    )Úannotations)Ú	timedeltaN)Ú
BaseOffset)Ú calculate_variable_window_bounds)Ú
set_module)Úensure_platform_int)ÚDatetimeIndex)ÚNanozpandas.api.indexersc                  ó2   — e Zd ZdZ	 ddd
„Z	 	 	 	 	 ddd„ZdS )ÚBaseIndexera•  
    Base class for window bounds calculations.

    Parameters
    ----------
    index_array : np.ndarray, default None
        Array-like structure representing the indices for the data points.
        If None, the default indices are assumed. This can be useful for
        handling non-uniform indices in data, such as in time series
        with irregular timestamps.
    window_size : int, default 0
        Size of the moving window. This is the number of observations used
        for calculating the statistic. The default is to consider all
        observations within the window.
    **kwargs
        Additional keyword arguments passed to the subclass's methods.

    See Also
    --------
    DataFrame.rolling : Provides rolling window calculations on dataframe.
    Series.rolling : Provides rolling window calculations on series.

    Examples
    --------
    >>> from pandas.api.indexers import BaseIndexer
    >>> class CustomIndexer(BaseIndexer):
    ...     def get_window_bounds(self, num_values, min_periods, center, closed, step):
    ...         start = np.arange(num_values, dtype=np.int64)
    ...         end = np.arange(num_values, dtype=np.int64) + self.window_size
    ...         return start, end
    >>> df = pd.DataFrame({"values": range(5)})
    >>> indexer = CustomIndexer(window_size=2)
    >>> df.rolling(indexer).sum()
        values
    0	1.0
    1	3.0
    2	5.0
    3	7.0
    4	4.0
    Nr   Úindex_arrayúnp.ndarray | NoneÚwindow_sizeÚintÚreturnÚNonec                óx   — || _         || _        |                     ¦   «         D ]\  }}t          | ||¦  «         Œd S )N)r   r   ÚitemsÚsetattr)Úselfr   r   ÚkwargsÚkeyÚvalues         úJC:\Projects\DSCons\.venv\Lib\site-packages\pandas\core\indexers\objects.pyÚ__init__zBaseIndexer.__init__?   sN   € ð 'ˆÔØ&ˆÔà Ÿ,š,™.œ.ð 	&ð 	&‰JˆC�Ý�D˜#˜uÑ%Ô%Ð%Ð%ð	&ð 	&ó    Ú
num_valuesÚmin_periodsú
int | NoneÚcenterúbool | NoneÚclosedú
str | NoneÚstepútuple[np.ndarray, np.ndarray]c                ó   — t           ‚)áT  
        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
        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
        )ÚNotImplementedError©r   r   r   r    r"   r$   s         r   Úget_window_boundszBaseIndexer.get_window_boundsH   s   € õB "Ð!r   )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*   © r   r   r   r      si   € € € € € ð'ð 'ðT IJð&ð &ð &ð &ð &ð Ø"&Ø"Ø!Øð!"ð !"ð !"ð !"ð !"ð !"ð !"r   r   c                  ó&   — e Zd ZdZ	 	 	 	 	 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                ó  — |s| j         dk    r| j         dz
  dz  }nd}t          j        d|z   |dz   |z   |d¬¦  «        }|| j         z
  }|dv r|dz  }|dv r|dz  }t          j        |d|¦  «        }t          j        |d|¦  «        }||fS )r'   r   é   é   Úint64©Údtype©ÚleftÚboth)r;   Úneither)r   ÚnpÚarangeÚclip)	r   r   r   r    r"   r$   ÚoffsetÚendÚstarts	            r   r*   z$FixedWindowIndexer.get_window_boundso   s¿   € ðB ð 	�TÔ%¨Ò*Ð*ØÔ&¨Ñ*¨qÑ0ˆFˆFàˆFåŒi˜˜F™
 J°¡N°VÑ$;¸TÈÐQÑQÔQˆØ�dÔ&Ñ&ˆØÐ%Ð%Ð%Ø�Q‰JˆEØÐ(Ð(Ð(Ø�1‰HˆCåŒg�c˜1˜jÑ)Ô)ˆÝ”˜˜q *Ñ-Ô-ˆà�cˆzÐr   r+   r,   ©r-   r.   r/   r0   r*   r1   r   r   r3   r3   l   sD   € € € € € Ø=Ð=ð Ø"&Ø"Ø!Øð0ð 0ð 0ð 0ð 0ð 0ð 0r   r3   c                  ó&   — e Zd ZdZ	 	 	 	 	 ddd„ZdS )Ú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                ó°   — | j         €J ‚t          | j         ¦  «        x}|k     rt          d|› d|› d�¦  «        ‚t          || j        |||| j         ¦  «        S )r'   Nz\Variable rolling window requires the index to be at least as long as the 'other' index. Got z < z\. Please align 'other' to the rolling object's index using reindex_like() or similar method.)r   ÚlenÚ
ValueErrorr   r   )r   r   r   r    r"   r$   Úindex_lengths          r   r*   z'VariableWindowIndexer.get_window_bounds¥   s‘   € ðB ÔÐ+Ð+Ð+Ý Ô 0Ñ1Ô1Ð1ˆL°ZÒ?Ð?Ýð4Ø-9ð4ð 4Ø>Hð4ð 4ð 4ñô ð õ 0ØØÔØØØØÔñ
ô 
ð 	
r   r+   r,   rD   r1   r   r   rF   rF   ¢   sD   € € € € € ØXÐXð Ø"&Ø"Ø!Øð2
ð 2
ð 2
ð 2
ð 2
ð 2
ð 2
r   rF   c                  óB   ‡ — e Zd ZdZ	 	 	 	 ddˆ fd„Z	 	 	 	 	 ddd„Zˆ xZS )ÚVariableOffsetWindowIndexera–  
    Calculate window boundaries based on a non-fixed offset such as a BusinessDay.

    Parameters
    ----------
    index_array : np.ndarray, default 0
        Array-like structure specifying the indices for data points.
        This parameter is currently not used.

    window_size : int, optional, default 0
        Specifies the number of data points in each window.
        This parameter is currently not used.

    index : DatetimeIndex, optional
        ``DatetimeIndex`` of the labels of each observation.

    offset : BaseOffset, optional
        ``DateOffset`` representing the size of the window.

    **kwargs
        Additional keyword arguments passed to the parent class ``BaseIndexer``.

    See Also
    --------
    api.indexers.BaseIndexer : Base class for all indexers.
    DataFrame.rolling : Rolling window calculations on DataFrames.
    offsets : Module providing various time offset classes.

    Examples
    --------
    >>> from pandas.api.indexers import VariableOffsetWindowIndexer
    >>> df = pd.DataFrame(range(10), index=pd.date_range("2020", periods=10))
    >>> offset = pd.offsets.BDay(1)
    >>> indexer = VariableOffsetWindowIndexer(index=df.index, offset=offset)
    >>> df
                0
    2020-01-01  0
    2020-01-02  1
    2020-01-03  2
    2020-01-04  3
    2020-01-05  4
    2020-01-06  5
    2020-01-07  6
    2020-01-08  7
    2020-01-09  8
    2020-01-10  9
    >>> df.rolling(indexer).sum()
                   0
    2020-01-01   0.0
    2020-01-02   1.0
    2020-01-03   2.0
    2020-01-04   3.0
    2020-01-05   7.0
    2020-01-06  12.0
    2020-01-07   6.0
    2020-01-08   7.0
    2020-01-09   8.0
    2020-01-10   9.0
    Nr   r   r   r   r   ÚindexúDatetimeIndex | NonerA   úBaseOffset | Noner   r   c                óê   •—  t          ¦   «         j        ||fi |¤Ž t          |t          ¦  «        st	          d¦  «        ‚|| _        t          |t          ¦  «        st	          d¦  «        ‚|| _        d S )Nzindex must be a DatetimeIndex.z(offset must be a DateOffset-like object.)Úsuperr   Ú
isinstancer	   rI   rM   r   rA   )r   r   r   rM   rA   r   Ú	__class__s         €r   r   z$VariableOffsetWindowIndexer.__init__  s{   ø€ ð 	�‰ŒÔ˜ kÐ<Ð<°VÐ<Ð<Ð<Ý˜%¥Ñ/Ô/ð 	?ÝÐ=Ñ>Ô>Ð>ØˆŒ
Ý˜&¥*Ñ-Ô-ð 	IÝÐGÑHÔHÐHØˆŒˆˆr   r   r   r   r    r!   r"   r#   r$   r%   c                óÂ  — |�t          d¦  «        ‚|dk    r,t          j        dd¬¦  «        t          j        dd¬¦  «        fS |€| j        �dnd}|dv }|d	v }| j        |d
z
           | j        d         k     rd}nd
}|| j        z  }	t          j        |d¬¦  «        }
|
                     d¦  «         t          j        |d¬¦  «        }|                     d¦  «         d|
d<   |rd
|d<   nd|d<   t          d¦  «        }t          d
|¦  «        D ]Î}| j        |         }||	z
  }|r|t          d
¦  «        z  }||
|<   t          |
|d
z
           |¦  «        D ]"}| j        |         |z
  |z  }||k    r||
|<    nŒ#| j        ||d
z
                    |z
  |z  }||k    r|s||d
z
           d
z   ||<   n||k    r	|d
z   ||<   n||d
z
           ||<   |s||xx         d
z  cc<   ŒÏ|
|fS )r'   Nz/step not implemented for variable offset windowr   r7   r8   Úrightr<   )rU   r<   r:   r5   éÿÿÿÿ)	r(   r>   ÚemptyrM   rA   Úfillr   Úranger
   )r   r   r   r    r"   r$   Úright_closedÚleft_closedÚindex_growth_signÚoffset_diffrC   rB   ÚzeroÚiÚ	end_boundÚstart_boundÚjÚ
start_diffÚend_diffs                      r   r*   z-VariableOffsetWindowIndexer.get_window_bounds(  sq  € ðB ÐÝ%Ð&WÑXÔXÐXØ˜Š?ˆ?Ý”8˜A WÐ-Ñ-Ô-­r¬x¸ÀÐ/IÑ/IÔ/IÐIÐIð ˆ>Ø $¤
Ð 6�W�W¸FˆFàÐ!2Ð2ˆØÐ 0Ð0ˆàŒ:�j 1‘nÔ%¨¬
°1¬Ò5Ð5Ø "ÐÐà !ÐØ'¨$¬+Ñ5ˆå”˜¨7Ð3Ñ3Ô3ˆØ�
Š
�2‰ŒˆÝŒh�z¨Ð1Ñ1Ô1ˆØ�Š�‰Œˆàˆˆa‰ð ð 	ØˆC�‰FˆFð ˆC�‰Få˜‰|Œ|ˆõ �q˜*Ñ%Ô%ð 	ð 	ˆAØœ
 1œˆIØ# kÑ1ˆKð ð 'Ø�t A™wœwÑ&�ð ˆE�!‰HÝ˜5  Q¡œ<¨Ñ+Ô+ð ð �Ø"œj¨œm¨kÑ9Ð=NÑN�
Ø Ò$Ð$Ø �E˜!‘HØ�Eð %ð œ
 3 q¨1¡u¤:Ô.°Ñ:Ð>OÑOˆHØ˜4ÒÐ¨ÐØ˜Q ™Uœ a™��A‘�Ø˜TÒ!Ð!Ø˜Q™��A‘�à˜Q ™Uœ��A‘ð  ð Ø�A��”˜!‘��‘øà�cˆzÐr   )Nr   NN)
r   r   r   r   rM   rN   rA   rO   r   r   r+   r,   )r-   r.   r/   r0   r   r*   Ú__classcell__©rS   s   @r   rL   rL   Ú   sŽ   ø€ € € € € ð:ð :ð| *.ØØ&*Ø$(ðð ð ð ð ð ð ð$ Ø"&Ø"Ø!Øðcð cð cð cð cð cð cð cð cr   rL   c                  ó&   — e Zd ZdZ	 	 	 	 	 ddd„ZdS )ÚExpandingIndexerz;Calculate expanding window bounds, mimicking df.expanding()r   Nr   r   r   r   r    r!   r"   r#   r$   r   r%   c                óŠ   — t          j        |t           j        ¬¦  «        t          j        d|dz   t           j        ¬¦  «        fS )r'   r8   r5   )r>   Úzerosr7   r?   r)   s         r   r*   z"ExpandingIndexer.get_window_bounds‘  s=   € õD ŒH�Z¥r¤xÐ0Ñ0Ô0ÝŒI�a˜ a™­r¬xÐ8Ñ8Ô8ð
ð 	
r   r+   r,   rD   r1   r   r   rh   rh   Ž  sD   € € € € € ØEÐEð Ø"&Ø"Ø!Øð$
ð $
ð $
ð $
ð $
ð $
ð $
r   rh   c                  ó&   — e Zd ZdZ	 	 	 	 	 ddd„ZdS )ÚFixedForwardWindowIndexeraö  
    Creates window boundaries for fixed-length windows that include the current row.

    Parameters
    ----------
    index_array : np.ndarray, default None
        Array-like structure representing the indices for the data points.
        If None, the default indices are assumed. This can be useful for
        handling non-uniform indices in data, such as in time series
        with irregular timestamps.
    window_size : int, default 0
        Size of the moving window. This is the number of observations used
        for calculating the statistic. The default is to consider all
        observations within the window.
    **kwargs
        Additional keyword arguments passed to the subclass's methods.

    See Also
    --------
    DataFrame.rolling : Provides rolling window calculations.
    api.indexers.VariableWindowIndexer : Calculate window bounds based on
        variable-sized windows.

    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                óÔ   — |rt          d¦  «        ‚|�t          d¦  «        ‚|€d}t          j        d||d¬¦  «        }|| j        z   }| j        rt          j        |d|¦  «        }||fS )r'   z.Forward-looking windows can't have center=TrueNzAForward-looking windows don't support setting the closed argumentr5   r   r7   r8   )rI   r>   r?   r   r@   )r   r   r   r    r"   r$   rC   rB   s           r   r*   z+FixedForwardWindowIndexer.get_window_boundsæ  s‘   € ðB ð 	OÝÐMÑNÔNÐNØÐÝØSñô ð ð ˆ<ØˆDå”	˜!˜Z¨°WÐ=Ñ=Ô=ˆØ�dÔ&Ñ&ˆØÔð 	.Ý”'˜#˜q *Ñ-Ô-ˆCà�cˆzÐr   r+   r,   rD   r1   r   r   rl   rl   ¸  sI   € € € € € ð*ð *ð\ Ø"&Ø"Ø!Øð/ð /ð /ð /ð /ð /ð /r   rl   c                  óD   ‡ — e Zd ZdZdddedfdˆ fd„Z	 	 	 	 	 ddd„Zˆ x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                óÌ   •— |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   Nr1   )rq   rs   Úcopyru   rQ   r   Úpop)r   r   r   rq   rs   ru   r   rS   s          €r   r   zGroupbyIndexer.__init__  sŠ   ø€ ð6  /Ð4°"ˆÔØ,ˆÔØ7EÐM˜n×1Ò1Ñ3Ô3Ð3È2ˆÔØ�‰ŒÔð 	
Ø#ØÔ+×/Ò/°¸{ÑKÔKð	
ð 	
ð ð	
ð 	
ð 	
ð 	
ð 	
r   r   r   r   r   r    r!   r"   r#   r$   r%   c                óÈ  — g }g }d}| j                              ¦   «         D �]Ã}	| j        �(| j                             t	          |	¦  «        ¦  «        }
n| j        }
 | j        d
|
| j        dœ| j        ¤Ž}|                     t          |	¦  «        ||||¦  «        \  }}| 
                    t          j        ¦  «        }| 
                    t          j        ¦  «        }t          |¦  «        t          |¦  «        k    s
J d¦   «         ‚t          j        ||t          |	¦  «        z   ¦  «        }|t          |	¦  «        z  }t          j        ||d         dz   g¦  «         
                    t          j        d¬¦  «        }|                     |                     t	          |¦  «        ¦  «        ¦  «         |                     |                     t	          |¦  «        ¦  «        ¦  «         �ŒÅt          |¦  «        dk    r@t          j        g t          j        ¬	¦  «        t          j        g t          j        ¬	¦  «        fS t          j        |¦  «        }t          j        |¦  «        }||fS )r'   r   Nrw   z6these should be equal in length from get_window_boundsrV   r5   F)rx   r8   r1   )rq   Úvaluesr   Útaker   rs   r   ru   r*   rH   Úastyper>   r7   r?   ÚappendÚarrayÚconcatenate)r   r   r   r    r"   r$   Ústart_arraysÚ
end_arraysÚwindow_indices_startÚindicesr   ÚindexerrC   rB   Úwindow_indicess                  r   r*   z GroupbyIndexer.get_window_bounds?  sN  € ðH ˆØˆ
Ø ÐØÔ+×2Ò2Ñ4Ô4ð 	Mñ 	MˆGð ÔÐ+Ø"Ô.×3Ò3Õ4GÈÑ4PÔ4PÑQÔQ��à"Ô.�Ø)�dÔ)ð Ø'Ø Ô,ðð ð Ô%ðð ˆGð
 !×2Ò2Ý�G‘”˜k¨6°6¸4ñô ‰JˆE�3ð —L’L¥¤Ñ*Ô*ˆEØ—*’*�RœXÑ&Ô&ˆCÝ�u‘:”:¥ S¡¤Ò)Ð)Ð)ØHñ *Ô)Ð)õ
  œYØ$Ð&:½SÀ¹\¼\Ñ&Iñô ˆNð !¥C¨¡L¤LÑ0Ð åœY ~¸ÀrÔ8JÈQÑ8NÐ7OÑPÔP×WÒWÝ”˜uð Xñ ô ˆNð ×Ò × 3Ò 3Õ4GÈÑ4NÔ4NÑ OÔ OÑPÔPÐPØ×Ò˜n×1Ò1Õ2EÀcÑ2JÔ2JÑKÔKÑLÔLÐLÑLÝˆ|ÑÔ Ò!Ð!Ý”8˜B¥b¤hÐ/Ñ/Ô/µ´¸"ÅBÄHÐ1MÑ1MÔ1MÐMÐMÝ”˜|Ñ,Ô,ˆÝŒn˜ZÑ(Ô(ˆØ�cˆzÐr   )r   r   r   rp   rq   rr   rs   rt   ru   rr   r   r   r+   r,   )r-   r.   r/   r0   r   r   r*   re   rf   s   @r   ro   ro     s�   ø€ € € € € ØWÐWð *.Ø)*Ø'+Ø,7Ø&*ð"
ð "
ð "
ð "
ð "
ð "
ð "
ðL Ø"&Ø"Ø!ØðKð Kð Kð Kð Kð Kð Kð Kð Kr   ro   c                  ó&   — e Zd ZdZ	 	 	 	 	 ddd„ZdS )ÚExponentialMovingWindowIndexerz/Calculate ewm window bounds (the entire window)r   Nr   r   r   r   r    r!   r"   r#   r$   r   r%   c                ó†   — t          j        dgt           j        ¬¦  «        t          j        |gt           j        ¬¦  «        fS )r'   r   r8   )r>   r   r7   r)   s         r   r*   z0ExponentialMovingWindowIndexer.get_window_bounds�  s6   € õB Œx˜˜¥2¤8Ð,Ñ,Ô,­b¬h¸
°|Í2Ì8Ð.TÑ.TÔ.TÐTÐTr   r+   r,   rD   r1   r   r   rˆ   rˆ   �  sK   € € € € € Ø9Ð9ð Ø"&Ø"Ø!Øð!Uð !Uð !Uð !Uð !Uð !Uð !Ur   rˆ   )r0   Ú
__future__r   Údatetimer   Únumpyr>   Úpandas._libs.tslibsr   Úpandas._libs.window.indexersr   Úpandas.util._decoratorsr   Úpandas.core.dtypes.commonr   Úpandas.core.indexes.datetimesr	   Úpandas.tseries.offsetsr
   r   r3   rF   rL   rh   rl   ro   rˆ   r1   r   r   ú<module>r“      sx  ðØ RÐ Rà "Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ð Ð à Ð Ð Ð à *Ð *Ð *Ð *Ð *Ð *Ø IÐ IÐ IÐ IÐ IÐ IØ .Ð .Ð .Ð .Ð .Ð .à 9Ð 9Ð 9Ð 9Ð 9Ð 9à 7Ð 7Ð 7Ð 7Ð 7Ð 7à 'Ð 'Ð 'Ð 'Ð 'Ð 'ð €Ð!Ñ"Ô"ðT"ð T"ð T"ð T"ð T"ñ T"ô T"ñ #Ô"ðT"ðn3ð 3ð 3ð 3ð 3˜ñ 3ô 3ð 3ðl5
ð 5
ð 5
ð 5
ð 5
˜Kñ 5
ô 5
ð 5
ðp €Ð!Ñ"Ô"ðpð pð pð pð p +ñ pô pñ #Ô"ðpðf'
ð '
ð '
ð '
ð '
�{ñ '
ô '
ð '
ðT €Ð!Ñ"Ô"ð\ð \ð \ð \ð \ ñ \ô \ñ #Ô"ð\ð~rð rð rð rð r�[ñ rô rð rðj$Uð $Uð $Uð $Uð $U [ñ $Uô $Uð $Uð $Uð $Ur   