U
    sVc@                    @  s  U d dl mZ d dlZd dlmZ d dlmZ d dlmZm	Z	m
Z
mZmZmZ d dlZd dlZd dlmZ d dlmZmZmZmZmZmZmZ d dlmZmZmZmZm Z m!Z! d d	l"m#Z$ d d
l%m&Z&m'Z' d dl(m)Z)m*Z*m+Z+m,Z, d dl-m.Z. d dl/m0Z0m1Z1 d dl2m3  m4Z5 d dl6m7Z7 d dl8m9Z9 d dl:m3  m;Z< d dl=m>Z>m?Z? d dl@mAZA d dlBmCZCmDZDmEZEmFZF d dlGmHZH d dlImJZJ d dlKmLZLmMZM d dlNmOZOmPZP d dlQmRZRmSZS d dlTmUZUmVZV d dlWmXZXmYZYmZZZm[Z[ erd dl\m]Z]m^Z^m_Z_ i Z`dead< G dd deCe9ZbeDfdd d!d"d#d$d%Zcd&D ]Zdecedd' q2d(D ]Zdecedd) qHd*D ]Zdecedd+ q^d,D ]Zdecedd- qtd.D ]Zdecedd-eA qG d/d0 d0e9ZeG d1d2 d2ebZfG d3d4 d4eeefZgG d5d6 d6efZhG d7d8 d8eeehZiG d9d: d:efZjG d;d< d<eeejZkdmd=d>d?d@Zlebjmel_mdndAdBZnG dCdD dDeHZododEdFdGdHdEdIdJdKZpdpdNdNdOdPdQdRdSdTdUZqdqdVdVdOdPdQdWdSdXdYZrdZd[dZdHd\d]d^d_ZsdrdNdNdadPdQdRdSdbdcZtdsdEdedEdfdgdhZudidjdkdlZvdS )t    )annotationsN)	timedelta)dedent)TYPE_CHECKINGCallableHashableLiteralfinalno_type_check)lib)
BaseOffsetIncompatibleFrequencyNaTPeriod	Timedelta	Timestamp	to_offset)
IndexLabelNDFrameTTTimedeltaConvertibleTypesTimestampConvertibleTypesnpt)function)AbstractMethodError	DataError)AppenderSubstitutiondeprecate_nonkeyword_argumentsdoc)find_stack_level)ABCDataFrame	ABCSeries)ResamplerWindowApply)PandasObject)NDFrame_shared_docs)SeriesGroupBy)BaseGroupByGroupBy_pipe_templateget_groupby)Grouper)
BinGrouper)DatetimeIndex
date_range)PeriodIndexperiod_range)TimedeltaIndextimedelta_range)is_subperiodis_superperiod)
DateOffsetDayNanoTick)	DataFrameIndexSerieszdict[str, str]_shared_docs_kwargsc                	      sT  e Zd ZU dZded< e Zded< dddd	d
ddddg	Zdvej	ddddddddddZ
edd ZddddZdd d!d"Zed#dd$d%Zed&d' Zed(dd)d*Zd+d+d,d-d.Zd/d0 Zed1d2 Zed d3d4eed5d6d7 fd8d9Zed:Zed;Zeed< eed=d>d?dwd@dAZeZ eZ!dBdC Z"dDdE Z#dxdFdGZ$dyddHdIdJZ%dKdL Z&dMdN Z'dzdOdPZ(dQdR Z)d{dSdTZ*d|dUdVZ+d}dWdXZ,d~dYdZZ-dd[d\Z.dd]d^Z/e0dd_d`gdaee1j2fe3ddedfZ2ddgdhZ4diej	fddjdkdlZ5diej	fddjdmdnZ6ee7j8dodp Z8ee7j9dqdr Z9ddtduZ:  Z;S )	Resamplera/  
    Class for resampling datetimelike data, a groupby-like operation.
    See aggregate, transform, and apply functions on this object.

    It's easiest to use obj.resample(...) to use Resampler.

    Parameters
    ----------
    obj : Series or DataFrame
    groupby : TimeGrouper
    axis : int, default 0
    kind : str or None
        'period', 'timestamp' to override default index treatment

    Returns
    -------
    a Resampler of the appropriate type

    Notes
    -----
    After resampling, see aggregate, apply, and transform functions.
    r-   grouperzfrozenset[Hashable]
exclusionsfreqaxisclosedlabel
conventionloffsetkindoriginoffsetr   N)
group_keys	selectionzDataFrame | SeriesTimeGrouperintbool | lib.NoDefaultNone)objgroupbyrB   rJ   returnc                K  s   || _ d | _d| _|| _|| _d| _|| _d| _| j j| 	|dd | 
 \| _| _|| _| j jd k	rzt| j jg| _nt | _d S )NTF)sort)rQ   keysrS   rB   rG   ZsqueezerJ   Zas_index_set_grouper_convert_obj_get_binnerbinnerr?   
_selectionkey	frozensetr@   )selfrP   rQ   rB   rG   rJ   rK   kwargs r^   8/tmp/pip-unpacked-wheel-xj8nt62q/pandas/core/resample.py__init__   s    zResampler.__init__c                 K  sB   t || jr|j}| jD ]}||krt| |||< q| j|f|S )zE
        return a new object with the replacement attributes
        )
isinstance_constructorrP   _attributesgetattr)r\   rP   r]   attrr^   r^   r_   _shallow_copy   s    
zResampler._shallow_copystrrR   c                   s0    fdd j D }t j dd| dS )z@
        Provide a nice str repr of our rolling object.
        c                 3  s6   | ].}t  j|d d k	r| dt  j| V  qd S )N=)rd   rQ   ).0kr\   r^   r_   	<genexpr>   s   z$Resampler.__str__.<locals>.<genexpr>z [z, ])rc   type__name__join)r\   attrsr^   rl   r_   __str__   s    
zResampler.__str__)re   c                 C  sJ   || j krt| |S || jkr,t| j|S || jkr>| | S t| |S N)Z_internal_names_setobject__getattribute__rc   rd   rQ   rP   )r\   re   r^   r^   r_   __getattr__   s    


zResampler.__getattr__r%   c                 C  s   | j jS rt   )rQ   rP   rl   r^   r^   r_   rP      s    zResampler.objc                 C  s   | j jS rt   )rQ   axrl   r^   r^   r_   rx      s    zResampler.axboolc                 C  s"   | j dk	o | j jdk	p | j jdk	S )zP
        Is the resampling from a DataFrame column or MultiIndex level.
        N)rQ   rZ   levelrl   r^   r^   r_   _from_selection   s    
zResampler._from_selectionr   rP   rR   c                 C  s   |  S )z
        Provide any conversions for the object in order to correctly handle.

        Parameters
        ----------
        obj : Series or DataFrame

        Returns
        -------
        Series or DataFrame
        )Z_consolidate)r\   rP   r^   r^   r_   rV      s    zResampler._convert_objc                 C  s   t | d S rt   r   rl   r^   r^   r_   _get_binner_for_time   s    zResampler._get_binner_for_timec                 C  s<   |   \}}}t|t|ks"tt||| jjd}||fS )zk
        Create the BinGrouper, assume that self.set_grouper(obj)
        has already been called.
        )indexer)r~   lenAssertionErrorr-   rQ   r   )r\   rX   bins	binlabelsZbin_grouperr^   r^   r_   rW      s    zResampler._get_binnera  
    >>> df = pd.DataFrame({'A': [1, 2, 3, 4]},
    ...                   index=pd.date_range('2012-08-02', periods=4))
    >>> df
                A
    2012-08-02  1
    2012-08-03  2
    2012-08-04  3
    2012-08-05  4

    To get the difference between each 2-day period's maximum and minimum
    value in one pass, you can do

    >>> df.resample('2D').pipe(lambda x: x.max() - x.min())
                A
    2012-08-02  1
    2012-08-04  1)klassexamplesz/Callable[..., T] | tuple[Callable[..., T], str]r   )funcrR   c                   s   t  j|f||S rt   )superpipe)r\   r   argsr]   	__class__r^   r_   r     s    zResampler.pipea[  
    See Also
    --------
    DataFrame.groupby.aggregate : Aggregate using callable, string, dict,
        or list of string/callables.
    DataFrame.resample.transform : Transforms the Series on each group
        based on the given function.
    DataFrame.aggregate: Aggregate using one or more
        operations over the specified axis.
    a  
    Examples
    --------
    >>> s = pd.Series([1, 2, 3, 4, 5],
    ...               index=pd.date_range('20130101', periods=5, freq='s'))
    >>> s
    2013-01-01 00:00:00    1
    2013-01-01 00:00:01    2
    2013-01-01 00:00:02    3
    2013-01-01 00:00:03    4
    2013-01-01 00:00:04    5
    Freq: S, dtype: int64

    >>> r = s.resample('2s')

    >>> r.agg(np.sum)
    2013-01-01 00:00:00    3
    2013-01-01 00:00:02    7
    2013-01-01 00:00:04    5
    Freq: 2S, dtype: int64

    >>> r.agg(['sum', 'mean', 'max'])
                         sum  mean  max
    2013-01-01 00:00:00    3   1.5    2
    2013-01-01 00:00:02    7   3.5    4
    2013-01-01 00:00:04    5   5.0    5

    >>> r.agg({'result': lambda x: x.mean() / x.std(),
    ...        'total': np.sum})
                           result  total
    2013-01-01 00:00:00  2.121320      3
    2013-01-01 00:00:02  4.949747      7
    2013-01-01 00:00:04       NaN      5

    >>> r.agg(average="mean", total="sum")
                             average  total
    2013-01-01 00:00:00      1.5      3
    2013-01-01 00:00:02      3.5      7
    2013-01-01 00:00:04      5.0      5
    	aggregater:    )Zsee_alsor   r   rB   c                 O  s@   t | |||d }|d kr2|}| j|f||}| |}|S )N)r   r]   )r#   agg_groupby_and_aggregate_apply_loffset)r\   r   r   r]   resulthowr^   r^   r_   r   W  s    	
zResampler.aggregatec                 O  s   | j | jj|f||S )a  
        Call function producing a like-indexed Series on each group.

        Return a Series with the transformed values.

        Parameters
        ----------
        arg : function
            To apply to each group. Should return a Series with the same index.

        Returns
        -------
        transformed : Series

        Examples
        --------
        >>> s = pd.Series([1, 2],
        ...               index=pd.date_range('20180101',
        ...                                   periods=2,
        ...                                   freq='1h'))
        >>> s
        2018-01-01 00:00:00    1
        2018-01-01 01:00:00    2
        Freq: H, dtype: int64

        >>> resampled = s.resample('15min')
        >>> resampled.transform(lambda x: (x - x.mean()) / x.std())
        2018-01-01 00:00:00   NaN
        2018-01-01 01:00:00   NaN
        Freq: H, dtype: float64
        )_selected_objrQ   	transform)r\   argr   r]   r^   r^   r_   r   k  s     zResampler.transformc                 K  s   t | d S rt   r}   )r\   fr]   r^   r^   r_   _downsample  s    zResampler._downsamplec                 C  s   t | d S rt   r}   )r\   r   limit
fill_valuer^   r^   r_   	_upsample  s    zResampler._upsample)ndimc                 C  sR   | j }|dkr| j}t|d|| j| jd}z
|| W S  tk
rL   | Y S X dS )  
        Sub-classes to define. Return a sliced object.

        Parameters
        ----------
        key : string / list of selections
        ndim : {1, 2}
            requested ndim of result
        subset : object, default None
            subset to act on
        NZbyr?   rB   rJ   )r?   rP   r+   rB   rJ   KeyError)r\   rZ   r   subsetr?   groupedr^   r^   r_   _gotitem  s        
zResampler._gotitemc           	   
   O  s  | j }| jjdkr| j}n| j}t|d|| j| jd}z<t|tr^t	|r^|j
|f||}n|j|f||}W n tk
r   |j|f||}Y nn ttfk
r   |j|f||}Y nF tk
r } z&dt|krn |j|f||}W 5 d}~X Y nX | |}| |S )zA
        Re-evaluate the obj with a groupby aggregation.
           Nr   zMust produce aggregated value)r?   r   r   _obj_with_exclusionsr+   rB   rJ   ra   r!   callableZ_aggregate_item_by_itemr   r   applyAttributeErrorr   
ValueErrorrg   r   _wrap_result)	r\   r   r   r]   r?   rP   r   r   errr^   r^   r_   r     s4        $
z Resampler._groupby_and_aggregatec                 C  sJ   t | jtttjfo,t |jto,t|jdk}|r@|j| j |_d| _|S )a  
        If loffset is set, offset the result index.

        This is NOT an idempotent routine, it will be applied
        exactly once to the result.

        Parameters
        ----------
        result : Series or DataFrame
            the result of resample
        r   N)	ra   rF   r6   r   npZtimedelta64indexr.   r   )r\   r   Zneeds_offsetr^   r^   r_   r     s    

	zResampler._apply_loffsetc                 C  s   | j | ||dS )zG
        Return the correct class for resampling with groupby.
        rQ   rZ   )_resampler_for_grouping)r\   rQ   rZ   r^   r^   r_   _get_resampler_for_grouping  s    z%Resampler._get_resampler_for_groupingc                 C  s^   t |tr| jdk	r| j|_t |trZ|jrZ| j}t|jdd | jd|_t	|dd|_|S )z/
        Potentially wrap any results.
        Nr   rA   name)
ra   r"   rY   r   emptyrP   _asfreq_compatr   rA   rd   )r\   r   rP   r^   r^   r_   r      s    zResampler._wrap_resultc                 C  s   | j d|dS )a  
        Forward fill the values.

        Parameters
        ----------
        limit : int, optional
            Limit of how many values to fill.

        Returns
        -------
        An upsampled Series.

        See Also
        --------
        Series.fillna: Fill NA/NaN values using the specified method.
        DataFrame.fillna: Fill NA/NaN values using the specified method.
        ffillr   r   r\   r   r^   r^   r_   r     s    zResampler.ffillc                 C  s   t jdtt d | j|dS )a  
        Forward fill the values.

        .. deprecated:: 1.4
            Use ffill instead.

        Parameters
        ----------
        limit : int, optional
            Limit of how many values to fill.

        Returns
        -------
        An upsampled Series.
        zMpad is deprecated and will be removed in a future version. Use ffill instead.
stacklevelr   )warningswarnFutureWarningr    r   r   r^   r^   r_   pad#  s    zResampler.padc                 C  s   | j d|dS )a  
        Resample by using the nearest value.

        When resampling data, missing values may appear (e.g., when the
        resampling frequency is higher than the original frequency).
        The `nearest` method will replace ``NaN`` values that appeared in
        the resampled data with the value from the nearest member of the
        sequence, based on the index value.
        Missing values that existed in the original data will not be modified.
        If `limit` is given, fill only this many values in each direction for
        each of the original values.

        Parameters
        ----------
        limit : int, optional
            Limit of how many values to fill.

        Returns
        -------
        Series or DataFrame
            An upsampled Series or DataFrame with ``NaN`` values filled with
            their nearest value.

        See Also
        --------
        backfill : Backward fill the new missing values in the resampled data.
        pad : Forward fill ``NaN`` values.

        Examples
        --------
        >>> s = pd.Series([1, 2],
        ...               index=pd.date_range('20180101',
        ...                                   periods=2,
        ...                                   freq='1h'))
        >>> s
        2018-01-01 00:00:00    1
        2018-01-01 01:00:00    2
        Freq: H, dtype: int64

        >>> s.resample('15min').nearest()
        2018-01-01 00:00:00    1
        2018-01-01 00:15:00    1
        2018-01-01 00:30:00    2
        2018-01-01 00:45:00    2
        2018-01-01 01:00:00    2
        Freq: 15T, dtype: int64

        Limit the number of upsampled values imputed by the nearest:

        >>> s.resample('15min').nearest(limit=1)
        2018-01-01 00:00:00    1.0
        2018-01-01 00:15:00    1.0
        2018-01-01 00:30:00    NaN
        2018-01-01 00:45:00    2.0
        2018-01-01 01:00:00    2.0
        Freq: 15T, dtype: float64
        nearestr   r   r   r^   r^   r_   r   ;  s    :zResampler.nearestc                 C  s   | j d|dS )a  
        Backward fill the new missing values in the resampled data.

        In statistics, imputation is the process of replacing missing data with
        substituted values [1]_. When resampling data, missing values may
        appear (e.g., when the resampling frequency is higher than the original
        frequency). The backward fill will replace NaN values that appeared in
        the resampled data with the next value in the original sequence.
        Missing values that existed in the original data will not be modified.

        Parameters
        ----------
        limit : int, optional
            Limit of how many values to fill.

        Returns
        -------
        Series, DataFrame
            An upsampled Series or DataFrame with backward filled NaN values.

        See Also
        --------
        bfill : Alias of backfill.
        fillna : Fill NaN values using the specified method, which can be
            'backfill'.
        nearest : Fill NaN values with nearest neighbor starting from center.
        ffill : Forward fill NaN values.
        Series.fillna : Fill NaN values in the Series using the
            specified method, which can be 'backfill'.
        DataFrame.fillna : Fill NaN values in the DataFrame using the
            specified method, which can be 'backfill'.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Imputation_(statistics)

        Examples
        --------
        Resampling a Series:

        >>> s = pd.Series([1, 2, 3],
        ...               index=pd.date_range('20180101', periods=3, freq='h'))
        >>> s
        2018-01-01 00:00:00    1
        2018-01-01 01:00:00    2
        2018-01-01 02:00:00    3
        Freq: H, dtype: int64

        >>> s.resample('30min').bfill()
        2018-01-01 00:00:00    1
        2018-01-01 00:30:00    2
        2018-01-01 01:00:00    2
        2018-01-01 01:30:00    3
        2018-01-01 02:00:00    3
        Freq: 30T, dtype: int64

        >>> s.resample('15min').bfill(limit=2)
        2018-01-01 00:00:00    1.0
        2018-01-01 00:15:00    NaN
        2018-01-01 00:30:00    2.0
        2018-01-01 00:45:00    2.0
        2018-01-01 01:00:00    2.0
        2018-01-01 01:15:00    NaN
        2018-01-01 01:30:00    3.0
        2018-01-01 01:45:00    3.0
        2018-01-01 02:00:00    3.0
        Freq: 15T, dtype: float64

        Resampling a DataFrame that has missing values:

        >>> df = pd.DataFrame({'a': [2, np.nan, 6], 'b': [1, 3, 5]},
        ...                   index=pd.date_range('20180101', periods=3,
        ...                                       freq='h'))
        >>> df
                               a  b
        2018-01-01 00:00:00  2.0  1
        2018-01-01 01:00:00  NaN  3
        2018-01-01 02:00:00  6.0  5

        >>> df.resample('30min').bfill()
                               a  b
        2018-01-01 00:00:00  2.0  1
        2018-01-01 00:30:00  NaN  3
        2018-01-01 01:00:00  NaN  3
        2018-01-01 01:30:00  6.0  5
        2018-01-01 02:00:00  6.0  5

        >>> df.resample('15min').bfill(limit=2)
                               a    b
        2018-01-01 00:00:00  2.0  1.0
        2018-01-01 00:15:00  NaN  NaN
        2018-01-01 00:30:00  NaN  3.0
        2018-01-01 00:45:00  NaN  3.0
        2018-01-01 01:00:00  NaN  3.0
        2018-01-01 01:15:00  NaN  NaN
        2018-01-01 01:30:00  6.0  5.0
        2018-01-01 01:45:00  6.0  5.0
        2018-01-01 02:00:00  6.0  5.0
        bfillr   r   r   r^   r^   r_   r   w  s    dzResampler.bfillc                 C  s   t jdtt d | j|dS )ac  
        Backward fill the values.

        .. deprecated:: 1.4
            Use bfill instead.

        Parameters
        ----------
        limit : int, optional
            Limit of how many values to fill.

        Returns
        -------
        Series, DataFrame
            An upsampled Series or DataFrame with backward filled NaN values.
        zRbackfill is deprecated and will be removed in a future version. Use bfill instead.r   r   )r   r   r   r    r   r   r^   r^   r_   backfill  s    zResampler.backfillc                 C  s   | j ||dS )a  
        Fill missing values introduced by upsampling.

        In statistics, imputation is the process of replacing missing data with
        substituted values [1]_. When resampling data, missing values may
        appear (e.g., when the resampling frequency is higher than the original
        frequency).

        Missing values that existed in the original data will
        not be modified.

        Parameters
        ----------
        method : {'pad', 'backfill', 'ffill', 'bfill', 'nearest'}
            Method to use for filling holes in resampled data

            * 'pad' or 'ffill': use previous valid observation to fill gap
              (forward fill).
            * 'backfill' or 'bfill': use next valid observation to fill gap.
            * 'nearest': use nearest valid observation to fill gap.

        limit : int, optional
            Limit of how many consecutive missing values to fill.

        Returns
        -------
        Series or DataFrame
            An upsampled Series or DataFrame with missing values filled.

        See Also
        --------
        bfill : Backward fill NaN values in the resampled data.
        ffill : Forward fill NaN values in the resampled data.
        nearest : Fill NaN values in the resampled data
            with nearest neighbor starting from center.
        interpolate : Fill NaN values using interpolation.
        Series.fillna : Fill NaN values in the Series using the
            specified method, which can be 'bfill' and 'ffill'.
        DataFrame.fillna : Fill NaN values in the DataFrame using the
            specified method, which can be 'bfill' and 'ffill'.

        References
        ----------
        .. [1] https://en.wikipedia.org/wiki/Imputation_(statistics)

        Examples
        --------
        Resampling a Series:

        >>> s = pd.Series([1, 2, 3],
        ...               index=pd.date_range('20180101', periods=3, freq='h'))
        >>> s
        2018-01-01 00:00:00    1
        2018-01-01 01:00:00    2
        2018-01-01 02:00:00    3
        Freq: H, dtype: int64

        Without filling the missing values you get:

        >>> s.resample("30min").asfreq()
        2018-01-01 00:00:00    1.0
        2018-01-01 00:30:00    NaN
        2018-01-01 01:00:00    2.0
        2018-01-01 01:30:00    NaN
        2018-01-01 02:00:00    3.0
        Freq: 30T, dtype: float64

        >>> s.resample('30min').fillna("backfill")
        2018-01-01 00:00:00    1
        2018-01-01 00:30:00    2
        2018-01-01 01:00:00    2
        2018-01-01 01:30:00    3
        2018-01-01 02:00:00    3
        Freq: 30T, dtype: int64

        >>> s.resample('15min').fillna("backfill", limit=2)
        2018-01-01 00:00:00    1.0
        2018-01-01 00:15:00    NaN
        2018-01-01 00:30:00    2.0
        2018-01-01 00:45:00    2.0
        2018-01-01 01:00:00    2.0
        2018-01-01 01:15:00    NaN
        2018-01-01 01:30:00    3.0
        2018-01-01 01:45:00    3.0
        2018-01-01 02:00:00    3.0
        Freq: 15T, dtype: float64

        >>> s.resample('30min').fillna("pad")
        2018-01-01 00:00:00    1
        2018-01-01 00:30:00    1
        2018-01-01 01:00:00    2
        2018-01-01 01:30:00    2
        2018-01-01 02:00:00    3
        Freq: 30T, dtype: int64

        >>> s.resample('30min').fillna("nearest")
        2018-01-01 00:00:00    1
        2018-01-01 00:30:00    2
        2018-01-01 01:00:00    2
        2018-01-01 01:30:00    3
        2018-01-01 02:00:00    3
        Freq: 30T, dtype: int64

        Missing values present before the upsampling are not affected.

        >>> sm = pd.Series([1, None, 3],
        ...               index=pd.date_range('20180101', periods=3, freq='h'))
        >>> sm
        2018-01-01 00:00:00    1.0
        2018-01-01 01:00:00    NaN
        2018-01-01 02:00:00    3.0
        Freq: H, dtype: float64

        >>> sm.resample('30min').fillna('backfill')
        2018-01-01 00:00:00    1.0
        2018-01-01 00:30:00    NaN
        2018-01-01 01:00:00    NaN
        2018-01-01 01:30:00    3.0
        2018-01-01 02:00:00    3.0
        Freq: 30T, dtype: float64

        >>> sm.resample('30min').fillna('pad')
        2018-01-01 00:00:00    1.0
        2018-01-01 00:30:00    1.0
        2018-01-01 01:00:00    NaN
        2018-01-01 01:30:00    NaN
        2018-01-01 02:00:00    3.0
        Freq: 30T, dtype: float64

        >>> sm.resample('30min').fillna('nearest')
        2018-01-01 00:00:00    1.0
        2018-01-01 00:30:00    NaN
        2018-01-01 01:00:00    NaN
        2018-01-01 01:30:00    3.0
        2018-01-01 02:00:00    3.0
        Freq: 30T, dtype: float64

        DataFrame resampling is done column-wise. All the same options are
        available.

        >>> df = pd.DataFrame({'a': [2, np.nan, 6], 'b': [1, 3, 5]},
        ...                   index=pd.date_range('20180101', periods=3,
        ...                                       freq='h'))
        >>> df
                               a  b
        2018-01-01 00:00:00  2.0  1
        2018-01-01 01:00:00  NaN  3
        2018-01-01 02:00:00  6.0  5

        >>> df.resample('30min').fillna("bfill")
                               a  b
        2018-01-01 00:00:00  2.0  1
        2018-01-01 00:30:00  NaN  3
        2018-01-01 01:00:00  NaN  3
        2018-01-01 01:30:00  6.0  5
        2018-01-01 02:00:00  6.0  5
        r   r   )r\   methodr   r^   r^   r_   fillna  s     zResampler.fillnar\   r   )versionZallowed_argslinearFforwardc           
   
   K  s*   |  d}	|	jf |||||||d|S )zD
        Interpolate values according to different methods.
        asfreq)r   rB   r   inplacelimit_direction
limit_areadowncast)r   interpolate)
r\   r   rB   r   r   r   r   r   r]   r   r^   r^   r_   r     s    
zResampler.interpolatec                 C  s   | j d|dS )a6  
        Return the values at the new freq, essentially a reindex.

        Parameters
        ----------
        fill_value : scalar, optional
            Value to use for missing values, applied during upsampling (note
            this does not fill NaNs that already were present).

        Returns
        -------
        DataFrame or Series
            Values at the specified freq.

        See Also
        --------
        Series.asfreq: Convert TimeSeries to specified frequency.
        DataFrame.asfreq: Convert TimeSeries to specified frequency.
        r   )r   r   )r\   r   r^   r^   r_   r     s    zResampler.asfreqr   numeric_onlyc                 O  s   t d|| | jd||dS )a  
        Compute standard deviation of groups, excluding missing values.

        Parameters
        ----------
        ddof : int, default 1
            Degrees of freedom.
        numeric_only : bool, default False
            Include only `float`, `int` or `boolean` data.

            .. versionadded:: 1.5.0

        Returns
        -------
        DataFrame or Series
            Standard deviation of values within each group.
        stdddofr   nvvalidate_resampler_funcr   r\   r   r   r   r]   r^   r^   r_   r     s    zResampler.stdc                 O  s   t d|| | jd||dS )a  
        Compute variance of groups, excluding missing values.

        Parameters
        ----------
        ddof : int, default 1
            Degrees of freedom.

        numeric_only : bool, default False
            Include only `float`, `int` or `boolean` data.

            .. versionadded:: 1.5.0

        Returns
        -------
        DataFrame or Series
            Variance of values within each group.
        varr   r   r   r^   r^   r_   r     s    zResampler.varc                 C  sP   |  d}t| jsLddlm} | jjdkr6| jj}nd }|g |jd|d}|S )Nsizer   )r<   r   int64r   dtyper   )	r   r   rx   pandasr<   r   r   r   r   )r\   r   r<   r   r^   r^   r_   r     s    


zResampler.sizec                 C  sb   |  d}t| js^| jjdkr>t| jg |jd| jjd}n ddlm	} |g |j|j
dd}|S )Ncountr   r   r   r   )r:   )r   columnsr   )r   r   rx   r   r   ro   r   r   r   r:   r   )r\   r   r:   r^   r^   r_   r     s"    

      zResampler.count      ?c                 K  s   | j dd|i|S )a  
        Return value at the given quantile.

        Parameters
        ----------
        q : float or array-like, default 0.5 (50% quantile)

        Returns
        -------
        DataFrame or Series
            Quantile of values within each group.

        See Also
        --------
        Series.quantile
            Return a series, where the index is q and the values are the quantiles.
        DataFrame.quantile
            Return a DataFrame, where the columns are the columns of self,
            and the values are the quantiles.
        DataFrameGroupBy.quantile
            Return a DataFrame, where the coulmns are groupby columns,
            and the values are its quantiles.
        quantileq)r   )r   )r\   r   r]   r^   r^   r_   r     s    zResampler.quantile)r   N)N)NN)N)N)N)N)N)N)N)N)r   r   NFr   NN)N)r   )<rp   
__module____qualname____doc____annotations__r[   r@   rc   r   
no_defaultr`   r	   rf   rs   rw   propertyrP   rx   r{   rV   r~   rW   r   r   r*   r   r   Z_agg_see_also_docZ_agg_examples_docr   r&   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r   r=   r   r   r   r)   r   r   r   __classcell__r^   r^   r   r_   r>   i   s   
  




+
"
1



<
f

 !       


r>   rg   ztuple[str, ...]ro   rO   )r   r   
docs_classrR   c                   s   |dkst |dkr2tjdfddd fdd}nT|dkrTtjfdd fd	d}n2|d
krzdtjfddd
 fdd}n fdd}t| j|_tt | dS )z
    Add a kernel to Resampler.

    Arguments
    ---------
    name : str
        Name of the kernel.
    args : tuple
        Arguments of the method.
    docs_class : type
        Class to get kernel docstring from.
    )r   	min_countr   r   r^   r   r   rN   rM   c                   s4   t  || |tjkr$ dkr$d}| j ||dS )NsumFr   )r   r   r   r   r   )r\   r   r   r   r]   r   r^   r_   r   Q  s      z!_add_downsample_kernel.<locals>.fr   c                   s   t  || | j |dS )Nr   r   )r\   r   r   r]   r   r^   r_   r   c  s    r   r   c                   s   t  || | j ||dS )Nr   r   r   r   r^   r_   r   k  s    c                   s   t  || |  S rt   r   )r\   r   r]   r   r^   r_   r   w  s    N)r   r   r   rd   r   setattrr>   )r   r   r   r   r^   r   r_   _add_downsample_kernel8  s    r   )r   prodminmaxfirstlastr   )meanZmedianr   )Zsemr   )ohlcr^   )Znuniquec                   @  s\   e Zd ZU dZded< dZded< dddd	d
Zedd ZeZ	eZ
eZedddZdS )_GroupByMixinz)
    Provide the groupby facilities.
    z	list[str]rc   NzIndexLabel | NonerY   rO   rh   c              
   K  sv   |d kr|}| j D ]}t| |||t|| q|d| _|j| _|| _|| _d| j_d| jj	_t

|j| _d S )NrK   T)rc   r   getrd   rY   rX   rZ   _groupbyZmutatedr?   copyrQ   )r\   rP   parentrQ   rZ   r]   re   r^   r^   r_   r`     s    

z_GroupByMixin.__init__c                   s(    fdd}j |}|S )z
        Dispatch to _upsample; we are stripping all of the _upsample kwargs and
        performing the original function call on the grouped object.
        c                   s<   j | jd} ttr*t| f S | jf S )N)rQ   )rf   rQ   ra   rg   rd   r   )xr   r   r]   r\   r^   r_   r     s    
z"_GroupByMixin._apply.<locals>.func)r   r   r   )r\   r   r   r]   r   r   r^   r   r_   _apply  s    z_GroupByMixin._applyc                   s   |dkr j } fdd jD }z.t|trD j|krD| j  j| }W n tk
rj    j}Y nX d}|jdkrt	
|r||kst	|r|}t |f| |d|}|S )r   Nc                   s   i | ]}|t  |qS r^   )rd   )rj   re   rl   r^   r_   
<dictcomp>  s      z*_GroupByMixin._gotitem.<locals>.<dictcomp>   )rQ   r   rK   )rP   rc   ra   listrZ   appendr   
IndexErrorr   r   Z	is_scalarZis_list_likero   )r\   rZ   r   r   r]   rQ   rK   Znew_rsr^   rl   r_   r     s8    
  z_GroupByMixin._gotitem)NNN)N)rp   r   r   r   r   rY   r`   r
   r   r   r   r   r	   r   r^   r^   r^   r_   r     s   

r   c                      sJ   e Zd Zedd Zdd Zdd Zdd Zdd
dZ fddZ	  Z
S )DatetimeIndexResamplerc                 C  s   t S rt   )DatetimeIndexResamplerGroupbyrl   r^   r^   r_   r     s    z.DatetimeIndexResampler._resampler_for_groupingc                 C  s&   | j dkr| j| jS | j| jS Nperiod)rG   rQ   _get_time_period_binsrx   _get_time_binsrl   r^   r^   r_   r~     s    
z+DatetimeIndexResampler._get_binner_for_timec                 K  s   t |p|}| j}| jjdkr(| j}n| j}t|sr| }|j	| j
|_|jj
| j
ksnt|jj
| j
f|S |j
dk	s|jdk	rt| jjt|kr|dkr|  S |j| j| jdj|f|}| |}| |S )
        Downsample the cython defined function.

        Parameters
        ----------
        how : string / cython mapped function
        **kwargs : kw args passed to how function
        r   NrB   )comget_cython_funcrx   r   r   r   r   r   r   Z
_with_freqrA   r   inferred_freqr?   r   r   rQ   rB   r   r   r   )r\   r   r]   rx   rP   r   r^   r^   r_   r     s,    	 
z"DatetimeIndexResampler._downsamplec                 C  s(   | j dkr|dd }n|dd }|S )z|
        Adjust our binner when upsampling.

        The range of a new index should not be outside specified range
        rightr   N)rC   r\   rX   r^   r^   r_   _adjust_binner_for_upsample"  s    
z2DatetimeIndexResampler._adjust_binner_for_upsampleNc           	      C  s   | j rtd| jrtd| j}| j}| j}| |}|dkrpt|j	| j
krpt|t|krp| }||_n|j||||d}| |}| |S )a  
        Parameters
        ----------
        method : string {'backfill', 'bfill', 'pad',
            'ffill', 'asfreq'} method for upsampling
        limit : int, default None
            Maximum size gap to fill when reindexing
        fill_value : scalar, default None
            Value to use for missing values

        See Also
        --------
        .fillna: Fill NA/NaN values using the specified method.

        zaxis must be 0zvUpsampling from level= or on= selection is not supported, use .set_index(...) to explicitly set index to datetime-likeN)r   r   r   )rB   r   r{   r   rx   r   rX   r  r   r  rA   r   r   r   reindexr   r   )	r\   r   r   r   rx   rP   rX   Z	res_indexr   r^   r^   r_   r   .  s4    
   
z DatetimeIndexResampler._upsamplec                   s6   t  |}| jdkr2t|jts2|j| j|_|S r  )r   r   rG   ra   r   r0   	to_periodrA   )r\   r   r   r^   r_   r   \  s    z#DatetimeIndexResampler._wrap_result)NN)rp   r   r   r   r   r~   r   r  r   r   r   r^   r^   r   r_   r    s   
+
.r  c                   @  s   e Zd ZdZedd ZdS )r  z9
    Provides a resample of a groupby implementation
    c                 C  s   t S rt   )r  rl   r^   r^   r_   rb   k  s    z*DatetimeIndexResamplerGroupby._constructorNrp   r   r   r   r   rb   r^   r^   r^   r_   r  f  s   r  c                      sV   e Zd Zedd Z fddZddd fddZ fd	d
Zd fdd	Z  Z	S )PeriodIndexResamplerc                 C  s   t S rt   )PeriodIndexResamplerGroupbyrl   r^   r^   r_   r   q  s    z,PeriodIndexResampler._resampler_for_groupingc                   s"   | j dkrt  S | j| jS )N	timestamp)rG   r   r~   rQ   _get_period_binsrx   rl   r   r^   r_   r~   u  s    

z)PeriodIndexResampler._get_binner_for_timer   r|   c                   sJ   t  |}| jrd}t|| jd k	r.d| _| jdkrF|j| jd}|S )NzResampling from level= or on= selection with a PeriodIndex is not currently supported, use .set_index(...) to explicitly set indexr  r   )r   rV   r{   NotImplementedErrorrF   rG   to_timestamprE   )r\   rP   msgr   r^   r_   rV   z  s    

z!PeriodIndexResampler._convert_objc                   s   | j dkrt j|f|S t|p&|}| j}t|j| jrJ| j|f|S t	|j| jrr|dkrj| |S | 
 S |j| jkr| 
 S td|j d| j ddS )r  r  r   z
Frequency z cannot be resampled to z&, as they are not sub or super periodsN)rG   r   r   r	  r
  rx   r4   rA   r   r5   r   r   )r\   r   r]   rx   r   r^   r_   r     s    


z PeriodIndexResampler._downsampleNc           
        sl   | j dkrt j|||dS | j}| j}| j}|j| j| jd}|j	|||d}t
|||| jd}	| |	S )a  
        Parameters
        ----------
        method : {'backfill', 'bfill', 'pad', 'ffill'}
            Method for upsampling.
        limit : int, default None
            Maximum size gap to fill when reindexing.
        fill_value : scalar, default None
            Value to use for missing values.

        See Also
        --------
        .fillna: Fill NA/NaN values using the specified method.

        r  )r   r   r  )r   r   r  )rG   r   r   rx   rP   rX   r   rA   rE   Zget_indexer_take_new_indexrB   r   )
r\   r   r   r   rx   rP   	new_indexmembr   new_objr   r^   r_   r     s    
zPeriodIndexResampler._upsample)NN)
rp   r   r   r   r   r~   rV   r   r   r   r^   r^   r   r_   r  p  s   
$r  c                   @  s   e Zd ZdZedd ZdS )r  :
    Provides a resample of a groupby implementation.
    c                 C  s   t S rt   )r  rl   r^   r^   r_   rb     s    z(PeriodIndexResamplerGroupby._constructorNr  r^   r^   r^   r_   r    s   r  c                   @  s(   e Zd Zedd Zdd Zdd ZdS )TimedeltaIndexResamplerc                 C  s   t S rt   )TimedeltaIndexResamplerGroupbyrl   r^   r^   r_   r     s    z/TimedeltaIndexResampler._resampler_for_groupingc                 C  s   | j | jS rt   )rQ   _get_time_delta_binsrx   rl   r^   r^   r_   r~     s    z,TimedeltaIndexResampler._get_binner_for_timec                 C  s   |S )z
        Adjust our binner when upsampling.

        The range of a new index is allowed to be greater than original range
        so we don't need to change the length of a binner, GH 13022
        r^   r  r^   r^   r_   r    s    z3TimedeltaIndexResampler._adjust_binner_for_upsampleN)rp   r   r   r   r   r~   r  r^   r^   r^   r_   r     s   
r   c                   @  s   e Zd ZdZedd ZdS )r!  r  c                 C  s   t S rt   )r   rl   r^   r^   r_   rb     s    z+TimedeltaIndexResamplerGroupby._constructorNr  r^   r^   r^   r_   r!    s   r!  zGDatetimeIndexResampler | PeriodIndexResampler | TimedeltaIndexResamplerrh   c                 K  s   t f |}|j| |dS )z8
    Create a TimeGrouper and return our resampler.
    rG   )rL   _get_resampler)rP   rG   kwdstgr^   r^   r_   get_resampler  s    
r'  c           
      K  s4   t f ||d|}|j| j|d}	|	j| |jdS )zA
    Return our appropriate resampler when grouping as well.
    )rA   rZ   r#  r   )rL   r$  rP   r   rZ   )
rQ   ruler   fill_methodr   rG   onr]   r&  Z	resamplerr^   r^   r_   get_resampler_for_grouping  s    r+  c                      s   e Zd ZdZejd Zd(d	d	d
ddddddd	 fddZd)ddZd*ddddZddddZ	dd Z
d dd!d"Zddd#d$Zd%dd&d'Z  ZS )+rL   ah  
    Custom groupby class for time-interval grouping.

    Parameters
    ----------
    freq : pandas date offset or offset alias for identifying bin edges
    closed : closed end of interval; 'left' or 'right'
    label : interval boundary to use for labeling; 'left' or 'right'
    convention : {'start', 'end', 'e', 's'}
        If axis is PeriodIndex
    )rC   rD   r   rF   rG   rE   rH   rI   MinNr   r   	start_dayTz!Literal[('left', 'right')] | Nonez
str | Nonez*Literal[('start', 'end', 'e', 's')] | Nonez
int | Nonezstr | TimestampConvertibleTypesz TimedeltaConvertibleTypes | NonerN   rO   )	rC   rD   rG   rE   baserH   rI   rJ   rR   c              
     sV  |dkrt d| d|dkr0t d| d|
dkrHt d|
 dt|}ddd	d
dddh}|j}||ksd|kr|d |d |kr|d krd}|d krd}n:|dkr|d krd}|d krd}n|d krd}|d krd}|| _|| _|	| _|
d k	r|
nd| _|| _|| _	|| _
|| _|dkr2|| _nJzt|| _W n: t tfk
rz } zt d| d|W 5 d }~X Y nX z|d k	rt|nd | _W n: t tfk
r } zt d| d|W 5 d }~X Y nX d|d< |d k	r|d k	rt d|r t|tr t||j |j | _t|tr4t|}|| _t jf ||d| d S )N>   Nr  leftzUnsupported value z for `label`z for `closed`>   Nseendstartz for `convention`MAQZBMZBAZBQW-r  r2  end_dayr/  r1  )epochr3  r-  r2  r:  z|'origin' should be equal to 'epoch', 'start', 'start_day', 'end', 'end_day' or should be a Timestamp convertible type. Got 'z
' instead.z6'offset' should be a Timedelta convertible type. Got 'TrS   z6'offset' and 'base' cannot be present at the same time)rA   rB   )r   r   Z	rule_codefindrC   rD   rG   rE   r   r)  r   rJ   rH   r   	TypeErrorr   rI   ra   r9   nanosnrg   rF   r   r`   )r\   rA   rC   rD   r   rB   r)  r   rF   rG   rE   r.  rH   rI   rJ   r]   Z	end_typesr(  r   r   r^   r_   r`   2  st    &


zTimeGrouper.__init__c                 C  s   |  | | j}t|tr0t|| || j| jdS t|tsB|dkrXt|| || j| jdS t|t	rvt
|| | j| jdS tdt|j ddS )a_  
        Return my resampler or raise if we have an invalid axis.

        Parameters
        ----------
        obj : input object
        kind : string, optional
            'period','timestamp','timedelta' are valid

        Returns
        -------
        a Resampler

        Raises
        ------
        TypeError if incompatible axis

        )rQ   rG   rB   rJ   r  )rQ   rB   rJ   zVOnly valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of ''N)rU   rx   ra   r.   r  rB   rJ   r0   r  r2   r   r=  ro   rp   )r\   rP   rG   rx   r^   r^   r_   r$    s8    

        
   zTimeGrouper._get_resamplerry   )validatec                 C  s   |  |}|j|j|jfS rt   )r$  rX   r?   rP   )r\   rP   rA  rr^   r^   r_   _get_grouper  s    
zTimeGrouper._get_grouperr.   )rx   c           	   	   C  sF  t |tstdt|j t|dkrJtg | j|jd }}|g |fS t|	 |
 | j| j| j| jd\}}t| j|||j|jddd }}|j}| ||\}}tj||| j|jd}| jd	kr|}| jd	kr|d
d  }n| jd	kr|d
d  }|jr|dt}|dt}t|t|k r<|d t| }|||fS )N5axis must be a DatetimeIndex, but got an instance of r   datarA   r   rC   rH   rI   TZshift_forward)rA   r3  r2  tzr   Z	ambiguousZnonexistent)hasnansr  r   )ra   r.   r=  ro   rp   r   rA   r   _get_timestamp_range_edgesr   r   rC   rH   rI   r/   rH  asi8_adjust_bin_edgesr   Zgenerate_bins_dt64rI  rD   insertr   )	r\   rx   rX   labelsr   r   	ax_values	bin_edgesr   r^   r^   r_   r    sX    




   


zTimeGrouper._get_time_binsc                 C  s   | j dkr~t| j dr~| jdkrN|d }|td td }||jj}n|j}|d | kr|d d }|d d }n|j}||fS )NDr  r   r  )	rA   r5   rC   tz_localizer   r8   rH  rK  r   )r\   rX   rO  rP  r^   r^   r_   rL    s    

zTimeGrouper._adjust_bin_edgesr2   c                 C  s   t |tstdt|j t|sFtg | j|jd }}|g |fS | |	  }}| j
dkrl|| j7 }t||| j|jd }}|}| j
dkr|| j7 }|j|| j
d}| jr|| j7 }| jr|| j7 }|||fS )Nz6axis must be a TimedeltaIndex, but got an instance of rE  r  r3  r2  rA   r   r/  Zside)ra   r2   r=  ro   rp   r   rA   r   r   r   rC   r3   searchsortedrI   rF   )r\   rx   rX   rN  r3  r2  
end_stampsr   r^   r^   r_   r"    s2    



   




z TimeGrouper._get_time_delta_binsc                 C  s   t |tstdt|j | j}t|sJtg ||jd }}|g |fS t	|d |d ||jd }}|| 
|d }|jr||j}|j|dd}|||fS )	NrD  rE  r   r  rT  r0  r/  rU  )ra   r.   r=  ro   rp   rA   r   r0   r   r1   r   r  rH  rS  rV  )r\   rx   rA   rX   rN  rW  r   r^   r^   r_   r  >  s    

z!TimeGrouper._get_time_period_binsr0   c                 C  s  t |tstdt|j |j| j| jd}d}|jrRt	
|j}||j  }t|st	jg t	jd}tg | j|jd }}t|dkrt|||t|\}}}|||fS | jj}| j| j| jd}| j| jdd}	d}
t | jtr8t||	| j| j| j| jd\}}	t|| jt|| j }|j| }
|}t||	| j|jd }}|j}t|| }||d	 |d   }t	|d |d	 | |}||7 }||
8 }t|j||jd}|j|d
d}|dkrt||||\}}}|||fS )Nz3axis must be a PeriodIndex, but got an instance of r  r   )r   rE  r2  rG  rT  r  r/  rU  ) ra   r0   r=  ro   rp   r   rA   rE   rI  r   r   Z_isnanr   arrayr   r   _insert_nat_binr?  r   r   r9   _get_period_range_edgesrC   rH   rI   r   r1   rK  Zarange_datar   rV  )r\   rx   r  	nat_countr   rX   rN  Z	freq_multr3  r2  Z	bin_shiftZp_startZstart_offseti8Zexpected_bins_countZ	i8_extendrngZprngr^   r^   r_   r  T  s`    




   

zTimeGrouper._get_period_bins)r,  NNr   r   NNNNNNr-  NT)N)T)rp   r   r   r   r,   rc   r`   r$  rC  r  rL  r"  r  r  r   r^   r^   r   r_   rL     s0   
              $h
)?#rL   r   znpt.NDArray[np.intp]r;   rM   )rP   r   r  rB   rR   c                 C  sl   t | tr*t| j|}| j||| jdS t | tr`|dkrDtd| j	j
||dd}| |S tdd S )N)r   r   r   zaxis 1 is not supported)Znew_axisr   rB   z.'obj' should be either a Series or a DataFrame)ra   r"   algosZtake_ndZ_valuesrb   r   r!   r  Z_mgrZreindex_indexerr   )rP   r   r  rB   Z
new_valuesZnew_mgrr^   r^   r_   r    s    
  

r  r/  r-  r   r   zLiteral[('right', 'left')]zTimedelta | Noneztuple[Timestamp, Timestamp])r   r   rA   rC   rI   rR   c                 C  s   t |tr| j}t |tr6|jdk|dkkr6tdn|dkrJtd|d}t |tr|| d} |d}t |tr||d}t| |||||d\} }t |tr| |} ||}n@|  } | }|dkrt|	| } nt| | } t|| }| |fS )aW  
    Adjust the `first` Timestamp to the preceding Timestamp that resides on
    the provided offset. Adjust the `last` Timestamp to the following
    Timestamp that resides on the provided offset. Input Timestamps that
    already reside on the offset will be adjusted depending on the type of
    offset and the `closed` parameter.

    Parameters
    ----------
    first : pd.Timestamp
        The beginning Timestamp of the range to be adjusted.
    last : pd.Timestamp
        The ending Timestamp of the range to be adjusted.
    freq : pd.DateOffset
        The dateoffset to which the Timestamps will be adjusted.
    closed : {'right', 'left'}, default "left"
        Which side of bin interval is closed.
    origin : {'epoch', 'start', 'start_day'} or Timestamp, default 'start_day'
        The timestamp on which to adjust the grouping. The timezone of origin must
        match the timezone of the index.
        If a timestamp is not used, these values are also supported:

        - 'epoch': `origin` is 1970-01-01
        - 'start': `origin` is the first value of the timeseries
        - 'start_day': `origin` is the first day at midnight of the timeseries
    offset : pd.Timedelta, default is None
        An offset timedelta added to the origin.

    Returns
    -------
    A tuple of length 2, containing the adjusted pd.Timestamp objects.
    Nz4The origin must have the same timezone as the index.r;  z
1970-01-01)rH  rG  r/  )
ra   r9   rH  r   r   r7   rS  _adjust_dates_anchored	normalizerollback)r   r   rA   rC   rH   rI   Zindex_tzr^   r^   r_   rJ    s:    (






     


rJ  r   ztuple[Period, Period]c           
      C  s   t dd | |fD std|  }| }|| }||}	t||||||d\}}|t||  |} |t|	|  |}| |fS )al  
    Adjust the provided `first` and `last` Periods to the respective Period of
    the given offset that encompasses them.

    Parameters
    ----------
    first : pd.Period
        The beginning Period of the range to be adjusted.
    last : pd.Period
        The ending Period of the range to be adjusted.
    freq : pd.DateOffset
        The freq to which the Periods will be adjusted.
    closed : {'right', 'left'}, default "left"
        Which side of bin interval is closed.
    origin : {'epoch', 'start', 'start_day'}, Timestamp, default 'start_day'
        The timestamp on which to adjust the grouping. The timezone of origin must
        match the timezone of the index.

        If a timestamp is not used, these values are also supported:

        - 'epoch': `origin` is 1970-01-01
        - 'start': `origin` is the first value of the timeseries
        - 'start_day': `origin` is the first day at midnight of the timeseries
    offset : pd.Timedelta, default is None
        An offset timedelta added to the origin.

    Returns
    -------
    A tuple of length 2, containing the adjusted pd.Period objects.
    c                 s  s   | ]}t |tV  qd S rt   )ra   r   )rj   rP   r^   r^   r_   rm   )  s     z*_get_period_range_edges.<locals>.<genexpr>z3'first' and 'last' must be instances of type PeriodrG  )allr=  r  Zis_on_offsetrJ  rM   r  )
r   r   rA   rC   rH   rI   Zfirst_tsZlast_tsZadjust_firstZadjust_lastr^   r^   r_   rZ    s"    &
     
rZ  r0   z
np.ndarrayz+tuple[PeriodIndex, np.ndarray, PeriodIndex])rX   r   rN  r\  rR   c                 C  sD   |dkst ||7 }t|d|}| dt} |dt}| ||fS )Nr   )r   r   rM  r   )rX   r   rN  r\  r^   r^   r_   rY  ;  s    rY  r  r9   c                 C  s  d}|dkr|   j}nt|dkr(| j}ndt|tr:|j}nR|dkr|dkrN|n|d}|j| j |j }|dkrz|d7 }|||  } | j}||r|jnd7 }| j}|j}	|d k	r| d	} |	d k	r|d	}| j| |j }
|j| |j }|d
kr>|
dkr| j|
 }n| j|j }|dkr6|j|j|  }n|j}nD|
dkrT| j|
 }n| j}|dkrv|j|j|  }n|j|j }t|}t|}|d k	r|d	|}|	d k	r|d	|	}||fS )Nr   r-  r3  r9  r2  rQ  r/  r   UTCr  )	ra  valuera   r   ceilr>  tzinfoZ
tz_convertrS  )r   r   rA   rC   rH   rI   Zorigin_nanosZsub_freq_timesZfirst_tzinfoZlast_tzinfoZfoffsetrF   Zfresult_intZlresult_intZfresultZlresultr^   r^   r_   r`  M  sV    









r`  Fry   )rP   ra  rR   c                 C  s   t | jtrD|dk	rtd|dkr(d}|  }| jj||d|_njt| jdkrj|  }t| j||_nDt| j	 | j
 |d}| jj|_| j|||d}|r|j |_|S )z
    Utility frequency conversion method for Series/DataFrame.

    See :meth:`pandas.NDFrame.asfreq` for full documentation.
    Nz"'method' argument is not supportedEr  r   r   )r   r   )ra   r   r0   r  r   r   r   r   r/   r   r   r   r  ra  )rP   rA   r   r   ra  r   r  Zdtir^   r^   r_   r     s     
r   z,DatetimeIndex | PeriodIndex | TimedeltaIndex)r   c                 C  s|   t | dkrtdt| tr,| j|d}nLt| trLtg | j|| jd}n,t| trltg | j|| jd}nt	t
| |S )z
    Helper to mimic asfreq on (empty) DatetimeIndex and TimedeltaIndex.

    Parameters
    ----------
    index : PeriodIndex, DatetimeIndex, or TimedeltaIndex
    freq : DateOffset

    Returns
    -------
    same type as index
    r   zECan only set arbitrary freq for empty DatetimeIndex or TimedeltaIndexr   )r   rA   r   )r   r   ra   r0   r   r.   r   r   r2   r=  ro   )r   rA   r  r^   r^   r_   r     s    


r   )N)NNNNN)r   )r/  r-  N)r/  r-  N)r  r-  N)NNFN)w
__future__r   r   datetimer   textwrapr   typingr   r   r   r   r	   r
   r   Znumpyr   Zpandas._libsr   Zpandas._libs.tslibsr   r   r   r   r   r   r   Zpandas._typingr   r   r   r   r   r   Zpandas.compat.numpyr   r   Zpandas.errorsr   r   Zpandas.util._decoratorsr   r   r   r   Zpandas.util._exceptionsr    Zpandas.core.dtypes.genericr!   r"   Zpandas.core.algorithmscoreZ
algorithmsr_  Zpandas.core.applyr#   Zpandas.core.baser$   Zpandas.core.commoncommonr	  Zpandas.core.genericr%   r&   Zpandas.core.groupby.genericr'   Zpandas.core.groupby.groupbyr(   r)   r*   r+   Zpandas.core.groupby.grouperr,   Zpandas.core.groupby.opsr-   Zpandas.core.indexes.datetimesr.   r/   Zpandas.core.indexes.periodr0   r1   Zpandas.core.indexes.timedeltasr2   r3   Zpandas.tseries.frequenciesr4   r5   Zpandas.tseries.offsetsr6   r7   r8   r9   r   r:   r;   r<   r=   r   r>   r   r   r   r  r  r  r  r   r!  r'  r   r+  rL   r  rJ  rZ  rY  r`  r   r   r^   r^   r^   r_   <module>   s     $	        WK\{
k
 
         
   
    R   8   O    %