
    Mh9                    "   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r " S S5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\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)Appender)ensure_platform_int)DatetimeIndex)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                  v    \ rS rSrSr S     SS jjr\" \5           S	           S
S jj5       rSr	g)BaseIndexer.   a  
Base class for window bounds calculations.

Examples
--------
>>> from pandas.api.indexers import BaseIndexer
>>> class CustomIndexer(BaseIndexer):
...     def get_window_bounds(self, num_values, min_periods, center, closed, step):
...         start = np.empty(num_values, dtype=np.int64)
...         end = np.empty(num_values, dtype=np.int64)
...         for i in range(num_values):
...             start[i] = i
...             end[i] = i + 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         N/var/www/html/env/lib/python3.13/site-packages/pandas/core/indexers/objects.py__init__BaseIndexer.__init__H   s,     '& ,,.JCDu% )    c                    [         er   )NotImplementedErrorr   
num_valuesmin_periodscenterclosedsteps         r   get_window_boundsBaseIndexer.get_window_boundsQ   s
     "!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   get_window_bounds_docr$   __static_attributes__ r   r   r   r   .   s    4 IJ&,&BE&	& #$ "&"!""  " 	"
 " " 
'" %"r   r   c                  \    \ rS rSrSr\" \5           S           SS jj5       rSrg)FixedWindowIndexer]   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X4$ )Nr         int64dtypeleftboth)r@   neither)r   nparangeclip)	r   r   r    r!   r"   r#   offsetendstarts	            r   r$   $FixedWindowIndexer.get_window_bounds`   s     T%%*&&*q0FFiiF
JNV$;TQ&&&%%QJE((1HCggc1j)q*-zr   r5   r+   r,   	r.   r/   r0   r1   r2   r   r3   r$   r4   r5   r   r   r7   r7   ]   sh    =#$ "&"!   	
   
' %r   r7   c                  \    \ rS rSrSr\" \5           S           SS jj5       rSrg)VariableWindowIndexer{   zNCreates window boundaries that are of variable length, namely for time series.Nc                J    [        UU R                  UUUU R                  5      $ r   )r   r   r   r   s         r   r$   'VariableWindowIndexer.get_window_bounds~   s/     0
 	
r   r5   r+   r,   rJ   r5   r   r   rL   rL   {   sh    X#$ "&"!

  
 	

 
 
 
'
 %
r   rL   c                     ^  \ rS rSrSr    S         SU 4S jjjr\" \5           S           S	S jj5       rSr	U =r
$ )
VariableOffsetWindowIndexer   a  
Calculate window boundaries based on a non-fixed offset such as a BusinessDay.

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	   
ValueErrorindexr   rF   )r   r   r   rW   rF   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XR                  -  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XU'   [        XS	-
     U5       H$  nU R                  U   U-
  U-  nUU:  d  M   UX'     O   U R                  XS	-
        U-
  U-  nUU:X  a  U(       d  XS	-
     S	-   X'   OUU::  a  US	-   X'   O	XS	-
     X'   U(       a  M  X==   S	-  ss'   M     X4$ )Nz/step not implemented for variable offset windowr   r<   r=   rightrA   )r[   rA   r?   r:   )	r   rC   emptyrW   rF   fillr   ranger
   )r   r   r    r!   r"   r#   right_closedleft_closedindex_growth_signoffset_diffrH   rG   zeroi	end_boundstart_boundj
start_diffend_diffs                      r   r$   -VariableOffsetWindowIndexer.get_window_bounds   s    %&WXX?88AW-rxx/III > $

 6WFF!22 00::j1n%

15 " !'++573

2hhz1a CF CF| q*%A

1I#1K tAw& !H5Q<+"jjmk9=NN
$ EH	 , 

31u:.:>OOH4UaT!QU  <!; &> zr   )rW   rF   )Nr   NN)
r   r'   r   r(   rW   zDatetimeIndex | NonerF   zBaseOffset | Noner)   r*   r+   r,   )r.   r/   r0   r1   r2   r   r   r3   r$   r4   __classcell__rX   s   @r   rQ   rQ      s    !J *.&*$(&  $	
 " 
   #$ "&"!JJ  J 	J
 J J 
'J %Jr   rQ   c                  \    \ rS rSrSr\" \5           S           SS jj5       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$ )Nr=   r:   )rC   zerosr<   rD   r   s         r   r$   "ExpandingIndexer.get_window_bounds  s8     HHZrxx0IIaarxx8
 	
r   r5   r+   r,   rJ   r5   r   r   ro   ro     sh    E#$ "&"!

  
 	

 
 
 
'
 %
r   ro   c                  \    \ rS rSrSr\" \5           S           SS jj5       rSrg)FixedForwardWindowIndexeri)  ao  
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
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$ )Nz.Forward-looking windows can't have center=TruezAForward-looking windows don't support setting the closed argumentr:   r   r<   r=   )rV   rC   rD   r   rE   )r   r   r    r!   r"   r#   rH   rG   s           r   r$   +FixedForwardWindowIndexer.get_window_boundsB  sx     MNNS  <D		!ZW=&&&''#q*-Czr   r5   r+   r,   rJ   r5   r   r   rt   rt   )  sl    0 #$ "&"!   	
   
' %r   rt   c                     ^  \ rS rSrSrSSS\S4           SU 4S jjjr\" \5           S	           S
S jj5       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&   Nr5   )groupby_indiceswindow_indexercopyindexer_kwargsrT   r   pop)r   r   r   rz   r{   r}   r   rX   s          r   r   GroupbyIndexer.__init___  sb    6  /4",7En1132 	
#++//{K	
 	
r   c                   / n/ nSnU R                   R                  5        GH  u  pU 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  pU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                  " XS   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X4$ )
Nr   r&   z6these should be equal in length from get_window_boundsr\   r:   F)r|   r=   r5   )rz   r   r   taker   r{   r   r}   r$   lenastyperC   r<   rD   appendarrayconcatenate)r   r   r    r!   r"   r#   start_arrays
end_arrayswindow_indices_startr   indicesr   indexerrH   rG   window_indicess                   r   r$    GroupbyIndexer.get_window_bounds  s    
  00668LC +"..334G4PQ"..)) ' ,, %%G
 !22Gk6JE LL*E**RXX&Cu:"  HGH 
  YY$S\&IN !CL0 YY~r8JQ8N7OPWWu X N  3 34G4N OPn112Ec2JKL? 9@ |!88Bbhh/"BHH1MMM|,nnZ(zr   )rz   r}   r{   )r   r'   r   zint | BaseIndexerrz   dict | Noner{   ztype[BaseIndexer]r}   r   r)   r*   r+   r,   )r.   r/   r0   r1   r2   r   r   r   r3   r$   r4   rl   rm   s   @r   rx   rx   \  s    W *.)*'+,7&*"
&"
 '"
 %	"

 *"
 $"
 
"
 "
H #$ "&"!22  2 	2
 2 2 
'2 %2r   rx   c                  \    \ rS rSrSr\" \5           S           SS jj5       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$ )Nr   r=   )rC   r   r<   r   s         r   r$   0ExponentialMovingWindowIndexer.get_window_bounds  s1     xx288,bhh
|288.TTTr   r5   r+   r,   rJ   r5   r   r   r   r     sp    9#$ "&"!UU  U 	U
 U U 
'U %Ur   r   )r2   
__future__r   datetimer   numpyrC   pandas._libs.tslibsr   pandas._libs.window.indexersr   pandas.util._decoratorsr   pandas.core.dtypes.commonr   pandas.core.indexes.datetimesr	   pandas.tseries.offsetsr
   r3   r   r7   rL   rQ   ro   rt   rx   r   r5   r   r   <module>r      s    R "   * I , 9 7 ' 8," ,"^ <
K 
4+ D
{ 
$0 0fZ[ ZzU[ Ur   