Ë
    u™ãj�X  ã                  óˆ  — d Z ddlm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r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y)zLIndexer objects for computing start/end window bounds for rolling operationsé    )Úannotations)Ú	timedelta)ÚTYPE_CHECKINGN)Ú
BaseOffset)Ú calculate_variable_window_bounds)Ú
set_module)Úensure_platform_int)ÚDatetimeIndex)ÚNano)ÚHashable)ÚAnyzpandas.api.indexersc                  óP   — e Zd ZdZ	 d	 	 	 	 	 dd„Z	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)	ÚBaseIndexera7  
    Base class for window bounds calculations.

    Subclasses should implement ``get_window_bounds`` to define custom
    windowing logic for use with :meth:`DataFrame.rolling` or
    :meth:`Series.rolling`.

    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
    Nc                ój   — || _         || _        |j                  «       D ]  \  }}t        | ||«       Œ y )N)Úindex_arrayÚwindow_sizeÚitemsÚsetattr)Úselfr   r   ÚkwargsÚkeyÚvalues         úg/var/www/html/python-recuperauto-other/env/lib/python3.12/site-packages/pandas/core/indexers/objects.pyÚ__init__zBaseIndexer.__init__H   s9   € ð 'ˆÔØ&ˆÔà Ÿ,™,›.ò 	&‰JˆC�Ü�D˜#˜uÕ%ñ	&ó    c                ó   — t         ‚)á¤  
        Computes the bounds of a window.

        Parameters
        ----------
        num_values : int, default 0
            number of values that will be aggregated over
        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

        Returns
        -------
        A tuple of ndarray[int64]s, indicating the boundaries of each
        window
        )ÚNotImplementedError©r   Ú
num_valuesÚmin_periodsÚcenterÚclosedÚsteps         r   Úget_window_boundszBaseIndexer.get_window_boundsQ   s
   € ô: "Ð!r   )Nr   )r   únp.ndarray | Noner   ÚintÚreturnÚNone©r   NNNN©r    r'   r!   ú
int | Noner"   zbool | Noner#   z
str | Noner$   r,   r(   ztuple[np.ndarray, np.ndarray])Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   © r   r   r   r      s|   „ ñ+ð\ IJð&Ø,ð&ØBEð&à	ó&ð Ø"&Ø"Ø!Øð"àð"ð  ð"ð ð	"ð
 ð"ð ð"ð 
'ô"r   r   c                  ó:   — e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚFixedWindowIndexerz3Creates window boundaries that are of fixed length.Nc                ó8  — |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_boundst   s±   € ñ: �T×%Ñ%¨Ò*Ø×&Ñ&¨Ñ*¨qÑ0‰FàˆFä�i‰i˜˜F™
 J°¡N°VÑ$;¸TÈÔQˆØ�d×&Ñ&Ñ&ˆØÐ%Ñ%Ø�Q‰JˆEØÐ(Ñ(Ø�1‰HˆCä�g‰g�c˜1˜jÓ)ˆÜ—‘˜˜q *Ó-ˆà�cˆzÐr   r*   r+   ©r-   r.   r/   r0   r%   r1   r   r   r3   r3   q   sU   „ Ù=ð Ø"&Ø"Ø!Øð,àð,ð  ð,ð ð	,ð
 ð,ð ð,ð 
'ô,r   r3   c                  ó:   — e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚVariableWindowIndexerzNCreates window boundaries that are of variable length, namely for time series.Nc                ó¾   — | j                   €J ‚t        | j                   «      x}|k  rt        d|› d|› d�«      ‚t        || j                  |||| j                   «      S )r   z\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ƒ   € ð: ×ÑÐ+Ð+Ð+Ü × 0Ñ 0Ó1Ð1ˆL°ZÒ?Üð-Ø-9¨N¸#¸j¸\ð J4ð4óð ô 0ØØ×ÑØØØØ×Ñó
ð 	
r   r*   r+   rD   r1   r   r   rF   rF   £   sU   „ ÙXð Ø"&Ø"Ø!Øð.
àð.
ð  ð.
ð ð	.
ð
 ð.
ð ð.
ð 
'ô.
r   rF   c                  ój   ‡ — e Zd ZdZ	 	 	 	 d	 	 	 	 	 	 	 	 	 dˆ fd„Z	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zˆ xZS )ÚVariableOffsetWindowIndexeraH  
    Calculate window boundaries based on a non-fixed offset such as a BusinessDay.

    Unlike the default fixed-size window, this indexer uses a
    :class:`DateOffset` to determine variable-width window boundaries
    based on the datetime index of the data.

    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
    c                ó°   •— t        ‰| �  ||fi |¤Ž t        |t        «      st	        d«      ‚|| _        t        |t        «      st	        d«      ‚|| _        y )Nzindex must be a DatetimeIndex.z(offset must be a DateOffset-like object.)Úsuperr   Ú
isinstancer
   rI   Úindexr   rA   )r   r   r   rP   rA   r   Ú	__class__s         €r   r   z$VariableOffsetWindowIndexer.__init__  sS   ø€ ô 	‰Ñ˜ kÑ<°VÒ<Ü˜%¤Ô/ÜÐ=Ó>Ð>ØˆŒ
Ü˜&¤*Ô-ÜÐGÓHÐHØˆ�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¬«      }
|
j                  d
«       t        j                  |d¬«      }|j                  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  }||kD  sŒ||
|<    n | j                  ||d	z
        |z
  |z  }||k(  r|s||d	z
     d	z   ||<   n||k  r	|d	z   ||<   n||d	z
     ||<   |rŒ±||xx   d	z  cc<   Œ¿ |
|fS )r   z/step not implemented for variable offset windowr   r7   r8   Úrightr<   )rS   r<   r:   r5   éÿÿÿÿ)	r   r>   ÚemptyrP   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)  s   € ð: ÐÜ%Ð&WÓXÐXØ˜Š?Ü—8‘8˜A WÔ-¬r¯x©x¸ÀÔ/IÐIÐIð ˆ>Ø $§
¡
Ð 6‘W¸FˆFàÐ!2Ð2ˆØÐ 0Ð0ˆà�:‰:�j 1‘nÑ%¨¯
©
°1©Ò5Ø "Ñà !ÐØ'¨$¯+©+Ñ5ˆä—‘˜¨7Ô3ˆØ�
‰
�2ŒÜ�h‰h�z¨Ô1ˆØ�‰�Œàˆˆa‰ñ ØˆC�ŠFð ˆC�‰Fä˜‹|ˆô �q˜*Ó%ò 	ˆAØŸ
™
 1™ˆIØ# kÑ1ˆKñ Øœt A›wÑ&�ð ˆE�!‰HÜ˜5  Q¡™<¨Ó+ò �Ø"Ÿj™j¨™m¨kÑ9Ð=NÑN�
Ø Ó$Ø �E˜!‘HÙð	ð Ÿ
™
 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'   rP   zDatetimeIndex | NonerA   zBaseOffset | Noner(   r)   r*   r+   )r-   r.   r/   r0   r   r%   Ú__classcell__©rQ   s   @r   rL   rL   ×   s£   ø„ ñ>ðD *.ØØ&*Ø$(ðà&ðð ðð $ð	ð
 "ðð 
õð$ Ø"&Ø"Ø!Øð_àð_ð  ð_ð ð	_ð
 ð_ð ð_ð 
'÷_r   rL   c                  ó:   — e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚExpandingIndexerz;Calculate expanding window bounds, mimicking df.expanding()Nc                óž   — 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Ž  s8   € ô< �H‰H�Z¤r§x¡xÔ0Ü�I‰I�a˜ a™¬r¯x©xÔ8ð
ð 	
r   r*   r+   rD   r1   r   r   rf   rf   ‹  sU   „ ÙEð Ø"&Ø"Ø!Øð 
àð 
ð  ð 
ð ð	 
ð
 ð 
ð ð 
ð 
'ô 
r   rf   c                  ó:   — e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚFixedForwardWindowIndexeraÑ  
    Creates window boundaries for fixed-length windows that include the current row.

    This indexer produces forward-looking windows, where each window starts at
    the current row and extends ``window_size`` rows ahead, unlike the default
    backward-looking behavior of :meth:`DataFrame.rolling`.

    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
    Nc                óÜ   — |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=TruezAForward-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~   € ñ: ÜÐMÓNÐNØÐÜØSóð ð ˆ<ØˆDä—	‘	˜!˜Z¨°WÔ=ˆØ�d×&Ñ&Ñ&ˆØ×ÒÜ—'‘'˜#˜q *Ó-ˆCà�cˆzÐr   r*   r+   rD   r1   r   r   rj   rj   ±  sX   „ ñ.ðd Ø"&Ø"Ø!Øð+àð+ð  ð+ð ð	+ð
 ð+ð ð+ð 
'ô+r   rj   c                  óp   ‡ — 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   c                ó´   •— |xs i | _         || _        |r|j                  «       ni | _        t	        ‰| �  d|| j                  j                  d|«      dœ|¤Ž y)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   )Úgroupby_indicesÚwindow_indexerÚcopyÚindexer_kwargsrN   r   Úpop)r   r   r   rp   rq   rs   r   rQ   s          €r   r   zGroupByIndexer.__init__  sd   ø€ ð6  /Ò4°"ˆÔØ,ˆÔÙ7E˜n×1Ñ1Ô3È2ˆÔÜ‰Ñð 	
Ø#Ø×+Ñ+×/Ñ/°¸{ÓKñ	
ð ó	
r   c                óž  — g }g }d}| j                   j                  «       D �]¤  }	| j                  �%| j                  j                  t	        |	«      «      }
n| j                  }
 | j
                  d	|
| j                  dœ| j                  ¤Ž}|j                  t        |	«      ||||«      \  }}|j                  t        j                  «      }|j                  t        j                  «      }t        |«      t        |«      k(  sJ d«       ‚t        j                  ||t        |	«      z   «      }|t        |	«      z  }t        j                  ||d   dz   g«      j                  t        j                  d¬«      }|j                  |j                  t	        |«      «      «       |j                  |j                  t	        |«      «      «       �Œ§ t        |«      dk(  rJt        j                  g t        j                  ¬«      t        j                  g t        j                  ¬«      fS t        j                   |«      }t        j                   |«      }||fS )
r   r   ro   z6these should be equal in length from get_window_boundsrT   r5   F)rr   r8   r1   )rp   Úvaluesr   Útaker	   rq   r   rs   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_bounds8  s  € ð@ ˆØˆ
Ø ÐØ×+Ñ+×2Ñ2Ó4ó 	MˆGð ×ÑÐ+Ø"×.Ñ.×3Ñ3Ô4GÈÓ4PÓQ‘à"×.Ñ.�Ø)�d×)Ñ)ð Ø'Ø ×,Ñ,ñð ×%Ñ%ñˆGð
 !×2Ñ2Ü�G“˜k¨6°6¸4ó‰JˆE�3ð —L‘L¤§¡Ó*ˆEØ—*‘*œRŸX™XÓ&ˆCÜ�u“:¤ S£Ò)ð ØHóÐ)ô
  ŸY™YØ$Ð&:¼SÀ»\Ñ&IóˆNð !¤C¨£LÑ0Ð äŸY™Y ~¸ÀrÑ8JÈQÑ8NÐ7OÓP×WÑWÜ—‘˜uð Xó ˆNð ×Ñ × 3Ñ 3Ô4GÈÓ4NÓ OÔPØ×Ñ˜n×1Ñ1Ô2EÀcÓ2JÓKÖLð?	Mô@ ˆ|Ó Ò!Ü—8‘8˜B¤b§h¡hÔ/´·±¸"ÄBÇHÁHÔ1MÐMÐMÜ—‘˜|Ó,ˆÜ�n‰n˜ZÓ(ˆØ�cˆzÐr   )r   r&   r   zint | BaseIndexerrp   z!dict[Hashable, np.ndarray] | Nonerq   ztype[BaseIndexer]rs   zdict[str, Any] | Noner(   r)   r*   r+   )r-   r.   r/   r0   r   r   r%   rc   rd   s   @r   rm   rm     s®   ø„ ÙWð *.Ø)*Ø=AØ,7Ø04ð"
à&ð"
ð 'ð"
ð ;ð	"
ð
 *ð"
ð .ð"
ð 
õ"
ðL Ø"&Ø"Ø!ØðGàðGð  ðGð ð	Gð
 ðGð ðGð 
'÷Gr   rm   c                  ó:   — e Zd ZdZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚExponentialMovingWindowIndexerz/Calculate ewm window bounds (the entire window)Nc                óš   — t        j                  dgt         j                  ¬«      t        j                  |gt         j                  ¬«      fS )r   r   r8   )r>   rz   r7   r   s         r   r%   z0ExponentialMovingWindowIndexer.get_window_bounds…  s1   € ô: �x‰x˜˜¤2§8¡8Ô,¬b¯h©h¸
°|Ì2Ï8É8Ô.TÐTÐTr   r*   r+   rD   r1   r   r   rƒ   rƒ   ‚  s\   „ Ù9ð Ø"&Ø"Ø!ØðUàðUð  ðUð ð	Uð
 ðUð ðUð 
'ôUr   rƒ   ) r0   Ú
__future__r   Údatetimer   Útypingr   Únumpyr>   Úpandas._libs.tslibsr   Úpandas._libs.window.indexersr   Úpandas.util._decoratorsr   Úpandas.core.dtypes.commonr	   Úpandas.core.indexes.datetimesr
   Úpandas.tseries.offsetsr   Úcollections.abcr   r   r   r3   rF   rL   rf   rj   rm   rƒ   r1   r   r   ú<module>r�      sà   ðÙ Rå "å Ý  ã å *Ý IÝ .å 9å 7å 'áÝ(Ýñ Ð!Ó"÷T"ð T"ó #ðT"ôn/˜ô /ôd1
˜Kô 1
ñh Ð!Ó"ôp +ó pó #ðpôf#
�{ô #
ñL Ð!Ó"ô\ ó \ó #ð\ô~n�[ô nôb U [õ  Ur   