
    I 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         m/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/pandas/core/indexers/objects.py__init__BaseIndexer.__init__?   s,     '& ,,.JCDu% )    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)FixedWindowIndexerl   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$ )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0FFiiF
JNV$;TQ&&&%%QJE((1HCggc1j)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1L?--9N#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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$ )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?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   )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 HHZrxx0IIaarxx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		!ZW=&&&''#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",7En1132 	
#++//{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  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$ )
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4G +"..334G4PQ"..)) ' ,, %%G
 !22Gk6JE LL*E**RXX&Cu:S) 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? 5@ |!88Bbhh/"BHH1MMM|,nnZ(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 xx288,bhh
|288.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   