ó
    Ñ]jV[  ã                  ó`  • S r SSKJr  SSKJr  SSKrSSKJr  SSK	J
r
  SSKJr  SSKJr  SS	KJr  SS
KJr  \" S5       " S S5      5       r " S S\5      r " S S\5      r\" S5       " S S\5      5       r " S S\5      r\" S5       " S S\5      5       r " S S\5      r " S S\5      rg)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                  ó`   • \ rS rSrSr S     SS jjr     S	           S
S jjrSrg)ÚBaseIndexeré   a  
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
Nc                óf   • Xl         X l        UR                  5        H  u  pE[        XU5        M     g )N)Úindex_arrayÚwindow_sizeÚitemsÚsetattr)Úselfr   r   ÚkwargsÚkeyÚvalues         ÚY/home/mande/repo/quber/.venv/lib/python3.13/site-packages/pandas/core/indexers/objects.pyÚ__init__ÚBaseIndexer.__init__?   s,   € ð 'ÔØ&Ôà Ÿ,™,ž.‰JˆCÜ�D˜uÖ%ò )ó    c                ó   • [         e)á¤  
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   Ú
num_valuesÚmin_periodsÚcenterÚclosedÚsteps         r   Úget_window_boundsÚBaseIndexer.get_window_boundsH   s   € ôB "Ð!r   ©r   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__Ú__firstlineno__Ú__doc__r   r$   Ú__static_attributes__© r   r   r   r      s�   † ñ'ðT IJð&Ø,ð&ØBEð&à	õ&ð Ø"&Ø"Ø!Øð!"àð!"ð  ð!"ð ð	!"ð
 ð!"ð ð!"ð 
'÷!"ð !"r   r   c                  óF   • \ rS rSrSr     S           SS jjrSrg)ÚFixedWindowIndexerél   z3Creates window boundaries that are of fixed length.Nc                óH  • U(       d  U R                   S:X  a  U R                   S-
  S-  nOSn[        R                  " SU-   US-   U-   USS9nXpR                   -
  nUS;   a  US-  nUS;   a  US-  n[        R                  " USU5      n[        R                  " USU5      nX‡4$ )r   r   é   é   Úint64©Údtype©ÚleftÚboth)r?   Úneither)r   ÚnpÚarangeÚclip)	r   r   r    r!   r"   r#   ÚoffsetÚendÚstarts	            r   r$   Ú$FixedWindowIndexer.get_window_boundso   s®   € öB �T×%Ñ%¨Ó*Ø×&Ñ&¨Ñ*¨qÑ0‰FàˆFä�iŠi˜˜F™
 J°¡N°VÑ$;¸TÈÑQˆØ×&Ñ&Ñ&ˆØÐ%Ó%Ø�Q‰JˆEØÐ(Ó(Ø�1‰HˆCä�gŠg�c˜1˜jÓ)ˆÜ—’˜˜q *Ó-ˆàˆzÐr   r4   r+   r,   ©r.   r/   r0   r1   r2   r$   r3   r4   r   r   r6   r6   l   sZ   † Ù=ð Ø"&Ø"Ø!Øð0àð0ð  ð0ð ð	0ð
 ð0ð ð0ð 
'÷0ð 0r   r6   c                  óF   • \ rS rSrSr     S           SS jjrSrg)ÚVariableWindowIndexeré¢   zNCreates window boundaries that are of variable length, namely for time series.Nc                óÀ   • U R                   c   e[        U R                   5      =oa:  a  [        SU SU S35      e[        UU R                  UUUU R                   5      $ )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$   Ú'VariableWindowIndexer.get_window_bounds¥   s‚   € ðB ×ÑÑ+Ð+Ð+Ü × 0Ñ 0Ó1Ð1ˆLÓ?Üð-Ø-9¨N¸#¸j¸\ð J4ð4óð ô 0ØØ×ÑØØØØ×Ñó
ð 	
r   r4   r+   r,   rI   r4   r   r   rK   rK   ¢   sZ   † ÙXð Ø"&Ø"Ø!Øð2
àð2
ð  ð2
ð ð	2
ð
 ð2
ð ð2
ð 
'÷2
ð 2
r   rK   c                  ó|   ^ • \ rS rSrSr    S         SU 4S jjjr     S           S	S jjrSrU =r$ )
ÚVariableOffsetWindowIndexeréÚ   aÊ  
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
c                óÀ   >• [         TU ]  " X40 UD6  [        U[        5      (       d  [	        S5      eX0l        [        U[        5      (       d  [	        S5      eX@l        g )Nzindex must be a DatetimeIndex.z(offset must be a DateOffset-like object.)Úsuperr   Ú
isinstancer	   rO   Úindexr   rE   )r   r   r   rX   rE   r   Ú	__class__s         €r   r   Ú$VariableOffsetWindowIndexer.__init__  sS   ø€ ô 	‰Ò˜Ñ<°VÒ<Ü˜%¤×/Ñ/ÜÐ=Ó>Ð>ØŒ
Ü˜&¤*×-Ñ-ÜÐGÓHÐHØ�r   c                ó¸  • Ub  [        S5      eUS::  a*  [        R                  " SSS9[        R                  " SSS94$ Uc  U R                  b  SOSnUS;   nUS;   nU R                  US	-
     U R                  S   :  a  S
nOS	nX€R                  -  n	[        R                  " USS9n
U
R                  S
5        [        R                  " USS9nUR                  S
5        SU
S'   U(       a  S	US'   OSUS'   [        S5      n[        S	U5       HÈ  nU R                  U   nXé-
  nU(       a  U[        S	5      -  nXÚU'   [        X­S	-
     U5       H$  nU R                  U   U-
  U-  nUU:”  d  M   UX­'     O   U R                  X½S	-
        U-
  U-  nUU:X  a  U(       d  X½S	-
     S	-   X½'   OUU::  a  US	-   X½'   O	X½S	-
     X½'   U(       a  M¼  X½==   S	-  ss'   MÊ     X«4$ )r   z/step not implemented for variable offset windowr   r;   r<   Úrightr@   )r\   r@   r>   r9   éÿÿÿÿ)	r   rB   ÚemptyrX   rE   Úfillr   Úranger
   )r   r   r    r!   r"   r#   Úright_closedÚleft_closedÚindex_growth_signÚoffset_diffrG   rF   ÚzeroÚiÚ	end_boundÚstart_boundÚjÚ
start_diffÚend_diffs                      r   r$   Ú-VariableOffsetWindowIndexer.get_window_bounds(  sÿ  € ðB ÑÜ%Ð&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Ø#Ñ1ˆKö Øœt A›wÑ&�ð �!‰HÜ˜5 Q¡™<¨Ö+�Ø"Ÿj™j¨™m¨kÑ9Ð=NÑN�
Ø Õ$Ø �E‘HÙñ	 ,ð Ÿ
™
 3¨1¡u¡:Ñ.°Ñ:Ð>OÑOˆHØ˜4Ó®Ø ™U™ a™�’Ø˜TÓ!Ø˜Q™�’à ™U™�‘÷  �<Ø“˜!‘•ñ; &ð> ˆzÐr   )rX   rE   )Nr   NN)
r   r'   r   r(   rX   zDatetimeIndex | NonerE   zBaseOffset | Noner)   r*   r+   r,   )	r.   r/   r0   r1   r2   r   r$   r3   Ú__classcell__©rY   s   @r   rS   rS   Ú   s®   ø† ñ:ð| *.ØØ&*Ø$(ðà&ðð ðð $ð	ð
 "ðð 
÷ð ð$ Ø"&Ø"Ø!Øðcàðcð  ðcð ð	cð
 ðcð ðcð 
'÷có cr   rS   c                  óF   • \ rS rSrSr     S           SS jjrSrg)ÚExpandingIndexeriŽ  z;Calculate expanding window bounds, mimicking df.expanding()Nc                ó–   • [         R                  " U[         R                  S9[         R                  " SUS-   [         R                  S94$ )r   r<   r9   )rB   Úzerosr;   rC   r   s         r   r$   Ú"ExpandingIndexer.get_window_bounds‘  s9   € ôD �HŠH�Z¤r§x¡xÑ0Ü�IŠI�a˜ a™¬r¯x©xÑ8ð
ð 	
r   r4   r+   r,   rI   r4   r   r   rp   rp   Ž  sZ   † ÙEð Ø"&Ø"Ø!Øð$
àð$
ð  ð$
ð ð	$
ð
 ð$
ð ð$
ð 
'÷$
ð $
r   rp   c                  óF   • \ rS rSrSr     S           SS jjrSrg)ÚFixedForwardWindowIndexeri¸  a^  
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
Nc                óì   • U(       a  [        S5      eUb  [        S5      eUc  Sn[        R                  " SXSS9nX`R                  -   nU R                  (       a  [        R                  " USU5      nXg4$ )r   z.Forward-looking windows can't have center=TruezAForward-looking windows don't support setting the closed argumentr9   r   r;   r<   )rO   rB   rC   r   rD   )r   r   r    r!   r"   r#   rG   rF   s           r   r$   Ú+FixedForwardWindowIndexer.get_window_boundsæ  sy   € öB ÜÐMÓNÐNØÑÜØSóð ð ‰<ØˆDä—	’	˜!˜Z°WÑ=ˆØ×&Ñ&Ñ&ˆØ××Ü—'’'˜#˜q *Ó-ˆCàˆzÐr   r4   r+   r,   rI   r4   r   r   ru   ru   ¸  s]   † ñ*ð\ Ø"&Ø"Ø!Øð/àð/ð  ð/ð ð	/ð
 ð/ð ð/ð 
'÷/ð /r   ru   c                  ó‚   ^ • \ rS rSrSrSSS\S4           SU 4S jjjr     S	           S
S jjrSrU =r	$ )ÚGroupbyIndexeri  zMCalculate bounds to compute groupby rolling, mimicking df.groupby().rolling()Nr   c                óÈ   >• U=(       d    0 U l         X@l        U(       a  UR                  5       O0 U l        [        TU ]  " SUU R                  R                  SU5      S.UD6  g)a¬  
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&   Nr4   )Úgroupby_indicesÚwindow_indexerÚcopyÚindexer_kwargsrV   r   Úpop)r   r   r   r{   r|   r~   r   rY   s          €r   r   ÚGroupbyIndexer.__init__  sb   ø€ ð6  /×4°"ˆÔØ,ÔÞ7E˜n×1Ñ1Ô3È2ˆÔÜ‰Òð 	
Ø#Ø×+Ñ+×/Ñ/°¸{ÓKñ	
ð ó	
r   c                ó–  • / n/ nSnU R                   R                  5        GH¡  n	U R                  b%  U R                  R                  [	        U	5      5      n
OU R                  n
U R
                  " S	U
U R                  S.U R                  D6nUR                  [        U	5      X#XE5      u  pÍUR                  [        R                  5      nUR                  [        R                  5      n[        U5      [        U5      :X  d   S5       e[        R                  " Xˆ[        U	5      -   5      nU[        U	5      -  n[        R                  " XîS   S-   /5      R                  [        R                  SS9nUR                  UR                  [	        U5      5      5        UR                  UR                  [	        U5      5      5        GM¤     [        U5      S:X  aF  [        R                  " / [        R                  S9[        R                  " / [        R                  S94$ [        R                   " U5      n[        R                   " U5      nXÍ4$ )
r   r   r&   z6these should be equal in length from get_window_boundsr]   r9   F)r}   r<   r4   )r{   Úvaluesr   Útaker   r|   r   r~   r$   rN   ÚastyperB   r;   rC   ÚappendÚarrayÚconcatenate)r   r   r    r!   r"   r#   Ústart_arraysÚ
end_arraysÚwindow_indices_startÚindicesr   ÚindexerrG   rF   Úwindow_indicess                  r   r$   Ú GroupbyIndexer.get_window_bounds?  sø  € ðH ˆØˆ
Ø ÐØ×+Ñ+×2Ñ2×4ˆGð ×ÑÑ+Ø"×.Ñ.×3Ñ3Ô4GÈÓ4PÓQ‘à"×.Ñ.�Ø×)Ò)ð Ø'Ø ×,Ñ,ñð ×%Ñ%ñˆGð
 !×2Ñ2Ü�G“˜k°6ó‰JˆEð —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ñ? 5ô@ ˆ|Ó Ó!Ü—8’8˜B¤b§h¡hÑ/´·²¸"ÄBÇHÁHÑ1MÐMÐMÜ—’˜|Ó,ˆÜ�nŠn˜ZÓ(ˆØˆzÐr   )r{   r~   r|   )r   r'   r   zint | BaseIndexerr{   údict | Noner|   ztype[BaseIndexer]r~   r�   r)   r*   r+   r,   )
r.   r/   r0   r1   r2   r   r   r$   r3   rm   rn   s   @r   ry   ry     s¹   ø† ÙWð *.Ø)*Ø'+Ø,7Ø&*ð"
à&ð"
ð 'ð"
ð %ð	"
ð
 *ð"
ð $ð"
ð 
÷"
ð "
ðL Ø"&Ø"Ø!ØðKàðKð  ðKð ð	Kð
 ðKð ðKð 
'÷Kó Kr   ry   c                  óF   • \ rS rSrSr     S           SS jjrSrg)ÚExponentialMovingWindowIndexeri�  z/Calculate ewm window bounds (the entire window)Nc                ó’   • [         R                  " S/[         R                  S9[         R                  " U/[         R                  S94$ )r   r   r<   )rB   r†   r;   r   s         r   r$   Ú0ExponentialMovingWindowIndexer.get_window_bounds�  s2   € ôB �xŠx˜˜¤2§8¡8Ñ,¬b¯hªh¸
°|Ì2Ï8É8Ñ.TÐTÐTr   r4   r+   r,   rI   r4   r   r   r‘   r‘   �  sb   † Ù9ð Ø"&Ø"Ø!Øð!Uàð!Uð  ð!Uð ð	!Uð
 ð!Uð ð!Uð 
'÷!Uð !Ur   r‘   )r2   Ú
__future__r   Údatetimer   ÚnumpyrB   Úpandas._libs.tslibsr   Úpandas._libs.window.indexersr   Úpandas.util._decoratorsr   Úpandas.core.dtypes.commonr   Úpandas.core.indexes.datetimesr	   Úpandas.tseries.offsetsr
   r   r6   rK   rS   rp   ru   ry   r‘   r4   r   r   Ú<module>r�      sÔ   ðÙ Rå "å ã å *Ý IÝ .å 9å 7å 'ñ Ð!Ó"÷T"ð T"ó #ðT"ôn3˜ô 3ôl5
˜Kô 5
ñp Ð!Ó"ôp +ó pó #ðpôf'
�{ô '
ñT Ð!Ó"ô\ ó \ó #ð\ô~r�[ô rôj$U [õ $Ur   