U
    f/eL                     @  s  d dl mZ d dlmZmZ d dlmZ d dlZd dlZd dl	m
ZmZ d dlmZmZmZmZmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZmZm Z m!Z! d dl"m#Z# d dl$m%Z% d dl&m'Z'm(Z(m)Z)m*Z* d dl+m,  m-Z. d dl/m,  m0  m1Z2 d dl/m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8 d dl9m:Z: d dl;m<Z< e=e2j>Z>e>?ddi ddiZ@dd ZAe:dddge'jB e'dde:dd ge'G d!d" d"e5ZCd'd#d"d$d%d&ZDdS )(    )annotations)datetime	timedelta)HashableN)indexlib)
BaseOffsetNaTPeriod
ResolutionTick)DateParseErrorparse_time_string)DtypeDtypeObj)InvalidIndexError)doc)is_datetime64_any_dtype
is_integer	is_scalarpandas_dtype)PeriodDtype)is_valid_na_for_dtype)PeriodArrayperiod_arrayraise_on_incompatiblevalidate_dtype_freq)maybe_extract_name)DatetimeIndexOpsMixin)DatetimeIndexIndex)inherit_names)
Int64IndexZtarget_klasszPeriodIndex or list of Periodsklassr   c                 K  sJ   | d}|jdkr:| dd }t||d}| j|f|S | |f|S d S )Ndataint64freqr&   )popdtyper   _simple_new)clsdvaluesr&    r.   >/tmp/pip-unpacked-wheel-tiezk1ph/pandas/core/indexes/period.py_new_PeriodIndexE   s    

r0   strftime
start_timeZend_timeT)wrapZis_leap_yearZ_format_native_typesc                      s  e Zd ZU dZdZdgZded< ded< eZe	j
ZdZeejfd	dd
edJdd dddZeejdKddddZeeejjddddZeeejjddddZeeejjddddZdLddd d d!d"d#Zed$dd%d&Zd'd( Zd)dd*d+d,Zd-d$d$d. fd/d0Zeejdejfdd1 fd2d3Zeddd4d5Zeddd6d7Z  fd8d9Z!dMd:d;Z"ejfdd<d=d>Z#d?d@dAdBdCZ$d?dDdEdFZ%ddGdHdIZ&  Z'S )NPeriodIndexa  
    Immutable ndarray holding ordinal values indicating regular periods in time.

    Index keys are boxed to Period objects which carries the metadata (eg,
    frequency information).

    Parameters
    ----------
    data : array-like (1d int np.ndarray or PeriodArray), optional
        Optional period-like data to construct index with.
    copy : bool
        Make a copy of input ndarray.
    freq : str or period object, optional
        One of pandas period strings or corresponding objects.
    year : int, array, or Series, default None
    month : int, array, or Series, default None
    quarter : int, array, or Series, default None
    day : int, array, or Series, default None
    hour : int, array, or Series, default None
    minute : int, array, or Series, default None
    second : int, array, or Series, default None
    dtype : str or PeriodDtype, default None

    Attributes
    ----------
    day
    dayofweek
    day_of_week
    dayofyear
    day_of_year
    days_in_month
    daysinmonth
    end_time
    freq
    freqstr
    hour
    is_leap_year
    minute
    month
    quarter
    qyear
    second
    start_time
    week
    weekday
    weekofyear
    year

    Methods
    -------
    asfreq
    strftime
    to_timestamp

    See Also
    --------
    Index : The base pandas Index type.
    Period : Represents a period of time.
    DatetimeIndex : Index with datetime64 data.
    TimedeltaIndex : Index of timedelta64 data.
    period_range : Create a fixed-frequency PeriodIndex.

    Examples
    --------
    >>> idx = pd.PeriodIndex(year=[2000, 2002], quarter=[1, 3])
    >>> idx
    PeriodIndex(['2000Q1', '2002Q3'], dtype='period[Q-DEC]')
    Zperiodindexnamer   _datar   r&   Tzpandas.arrays.PeriodArray)otherZ
other_nameNEstr)howreturnc                 C  s"   | j ||}t| j|| jdS Nr5   )r6   asfreqtyper*   r5   selfr&   r:   Zarrr.   r.   r/   r>      s    zPeriodIndex.asfreqstartr   )r;   c                 C  s   | j ||}tj|| jdS r<   )r6   to_timestampr   r*   r5   r@   r.   r.   r/   rC      s    zPeriodIndex.to_timestampr"   c                 C  s   t | jj| jdS r<   )r"   r6   hourr5   rA   r.   r.   r/   rD      s    zPeriodIndex.hourc                 C  s   t | jj| jdS r<   )r"   r6   minuter5   rE   r.   r.   r/   rF      s    zPeriodIndex.minutec                 C  s   t | jj| jdS r<   )r"   r6   secondr5   rE   r.   r.   r/   rG      s    zPeriodIndex.secondFzDtype | Noneboolr   )r)   copyr5   r;   c                 K  s  dddddddh}t ||sBtt || d }	td	|	 t||| }|d kr|d krtd d d ||\}}
|
}t||d
}nft||}|rt|| r|j	|kr|
|}|d kr|d k	rtj|tjd}t||d
}nt||d}|r| }| j||dS )NyearmonthdayZquarterrD   rF   rG   r   z-__new__() got an unexpected keyword argument r'   r)   )r$   r&   r=   )setissubsetlist	TypeErrorr   r   _generate_ranger   
isinstancer&   r>   npasarrayr%   r   rI   r*   )r+   r$   Zordinalr&   r)   rI   r5   fieldsZvalid_field_setargumentZfreq2r.   r.   r/   __new__   s4    


zPeriodIndex.__new__z
np.ndarrayc                 C  s   t j| tdS )NrM   )rT   rU   objectrE   r.   r.   r/   r-     s    zPeriodIndex.valuesc                 C  sx   t |ttjttjfr4t | jtrj| j|}|S n6t |t	r^|j
| jj
krR|jS t| |nt|rj|S t| ddS )a  
        Convert timedelta-like input to an integer multiple of self.freq

        Parameters
        ----------
        other : timedelta, np.timedelta64, DateOffset, int, np.ndarray

        Returns
        -------
        converted : int, np.ndarray[int64]

        Raises
        ------
        IncompatibleFrequency : if the input cannot be written as a multiple
            of self.freq.  Note IncompatibleFrequency subclasses ValueError.
        N)rS   r   rT   Ztimedelta64r   Zndarrayr&   r6   Z _check_timedeltalike_freq_compatr   basenr   r   )rA   r7   deltar.   r.   r/   _maybe_convert_timedelta  s    
z$PeriodIndex._maybe_convert_timedeltar   )r)   r;   c                 C  s   t |tsdS |j| jkS )zF
        Can we compare values of the given dtype to our own?
        F)rS   r   r&   )rA   r)   r.   r.   r/   _is_comparable_dtype7  s    
z PeriodIndex._is_comparable_dtyper    )wheremaskr;   c                   s<   t |trt|j| jd}nt |ts.tdt ||S )z
        where : array of timestamps
        mask : np.ndarray[bool]
            Array of booleans where data is not NA.
        r'   z6asof_locs `where` must be DatetimeIndex or PeriodIndex)rS   r   r4   Z_valuesr&   rQ   super	asof_locs)rA   r_   r`   	__class__r.   r/   rb   B  s
    

zPeriodIndex.asof_locsrI   c                   s^   t |}|tjk	r$tjdtdd nd}t|rNt|dd }| j|d	|S t
 j||dS )NzThe 'how' keyword in PeriodIndex.astype is deprecated and will be removed in a future version. Use index.to_timestamp(how=how) instead   )
stacklevelrB   tzr:   re   )r   r   
no_defaultwarningswarnFutureWarningr   getattrrC   Ztz_localizera   astype)rA   r)   rI   r:   rh   rc   r.   r/   ro   O  s    
zPeriodIndex.astypec                 C  sD   t | dkrdS | jstd| j}|dd |dd  dk  S )z
        Returns True if this PeriodIndex is range-like in that all Periods
        between start and end are present, in order.
        r   TzIndex is not monotonic   Nrf   )lenZis_monotonic_increasing
ValueErrorZasi8all)rA   r-   r.   r.   r/   is_fullf  s    zPeriodIndex.is_fullc                 C  s   dS )NZperiodr.   rE   r.   r.   r/   inferred_types  s    zPeriodIndex.inferred_typec                   s(   t  ||}| j|jkr$| |}|S N)ra   _convert_tolerancer)   r]   )rA   	tolerancetargetrc   r.   r/   rx   |  s    
zPeriodIndex._convert_tolerancec              
   C  sP  |}t |st|t|| jr(t}nt|tr2z| |}|W S  tt	fk
r\   Y nX zt
|| j\}}W n8 t	tfk
r } ztd| d|W 5 d}~X Y nX t|}	|	jj}
| jj}|
|kst|
|ks|	tjkr| jjjdkrt|| jd}| j|||d}|S |dkr,t|n|}nt|trp| j}|j}|j|jkrf|j|jkst|nXt|trzt|| jd}W n. t	k
r } zt||W 5 d}~X Y nX nt|zt|| jd}W n. t	k
r } zt||W 5 d}~X Y nX zt| |||W S  tk
rJ } zt||W 5 d}~X Y nX dS )a  
        Get integer location for requested label.

        Parameters
        ----------
        key : Period, NaT, str, or datetime
            String or datetime key must be parsable as Period.

        Returns
        -------
        loc : int or ndarray[int64]

        Raises
        ------
        KeyError
            Key is not present in the index.
        TypeError
            If key is listlike or otherwise not hashable.
        zCannot interpret 'z' as periodNBr'   )methodry   )r   r   r   r)   r	   rS   r9   _get_string_slicerQ   rs   r   r&   r   KeyErrorr   from_attrname
freq_groupvaluefreq_group_codeAssertionErrorZRESO_DAYr5   r
   get_locr[   Z_period_dtype_coder   r    )rA   keyr|   ry   Zorig_keylocZasdtreso_strerrresogrpfreqnZsfreqZkfreqr.   r.   r/   r     sh    
$





zPeriodIndex.get_loc)sidec           
   
   C  s   |dddt jfkst| |dd t|tr<t|| jdS t|trzt	|| j\}}W n0 t
k
r } z| d||W 5 d}~X Y nX t|}| ||\}}	|dkr|S |	S t|| jjs| d||S )	a  
        If label is a string or a datetime, cast it to Period.ordinal according
        to resolution.

        Parameters
        ----------
        label : object
        side : {'left', 'right'}
        kind : {'loc', 'getitem'}, or None

        Returns
        -------
        bound : Period or object

        Notes
        -----
        Value of `side` parameter should be validated in caller.

        r   getitemNkind_maybe_cast_slice_boundr'   sliceleft)r   rj   r   Z_deprecated_argrS   r   r
   r&   r9   r   rs   Z_invalid_indexerr   r   _parsed_string_to_boundsr6   Z_recognized_scalars)
rA   labelr   r   parsedr   r   r   lowerupperr.   r.   r/   r     s    

 
z#PeriodIndex._maybe_cast_slice_boundr   r   )r   r   c                 C  s4   |j }t||jd}|j| jdd|j| jddfS )Nr'   rB   ri   end)r   r
   r   r>   r&   )rA   r   r   r   Zivr.   r.   r/   r     s    z$PeriodIndex._parsed_string_to_bounds)r   c                 C  s:   t |tstt||f|j}| jj}|j|k s6td S rw   )	rS   r   r   r?   r   r)   r   r   rs   )rA   r   r   r   r.   r.   r/   _validate_partial_date_slice  s
    
z(PeriodIndex._validate_partial_date_slice)r   c              
   C  sZ   t || j\}}t|}z| ||W S  tk
rT } zt||W 5 d }~X Y nX d S rw   )r   r&   r   r   Z_partial_date_slicer~   )rA   r   r   r   r   r   r.   r.   r/   r}     s    
zPeriodIndex._get_string_slice)Nr8   )NrB   )NNNNFN)NN)(__name__
__module____qualname____doc__Z_typ_attributes__annotations__r   Z	_data_clslibindexZPeriodEngineZ_engine_typeZ!_supports_partial_string_indexingr   r>   _shared_doc_kwargsrC   propertyrD   fgetrF   rG   rX   r-   r]   r^   rb   r    ro   r   rj   ru   rv   rx   r   r   r   r   r}   __classcell__r.   r.   rc   r/   r4   P   sh   
E


      >$
^(r4   z
int | None)periodsr;   c                 C  sj   t | ||dkrtd|dkr:t| ts:t|ts:d}tj| |||i d\}}t||d}t||dS )a  
    Return a fixed frequency PeriodIndex.

    The day (calendar) is the default frequency.

    Parameters
    ----------
    start : str or period-like, default None
        Left bound for generating periods.
    end : str or period-like, default None
        Right bound for generating periods.
    periods : int, default None
        Number of periods to generate.
    freq : str or DateOffset, optional
        Frequency alias. By default the freq is taken from `start` or `end`
        if those are Period objects. Otherwise, the default is ``"D"`` for
        daily frequency.
    name : str, default None
        Name of the resulting PeriodIndex.

    Returns
    -------
    PeriodIndex

    Notes
    -----
    Of the three parameters: ``start``, ``end``, and ``periods``, exactly two
    must be specified.

    To learn more about the frequency strings, please see `this link
    <https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases>`__.

    Examples
    --------
    >>> pd.period_range(start='2017-01-01', end='2018-01-01', freq='M')
    PeriodIndex(['2017-01', '2017-02', '2017-03', '2017-04', '2017-05', '2017-06',
             '2017-07', '2017-08', '2017-09', '2017-10', '2017-11', '2017-12',
             '2018-01'],
            dtype='period[M]')

    If ``start`` or ``end`` are ``Period`` objects, they will be used as anchor
    endpoints for a ``PeriodIndex`` with frequency matching that of the
    ``period_range`` constructor.

    >>> pd.period_range(start=pd.Period('2017Q1', freq='Q'),
    ...                 end=pd.Period('2017Q2', freq='Q'), freq='M')
    PeriodIndex(['2017-03', '2017-04', '2017-05', '2017-06'],
                dtype='period[M]')
    rf   zOOf the three parameters: start, end, and periods, exactly two must be specifiedND)rV   r'   r=   )comZcount_not_noners   rS   r
   r   rR   r4   )rB   r   r   r&   r5   r$   r.   r.   r/   period_range(  s    4r   )NNNNN)E
__future__r   r   r   typingr   rk   ZnumpyrT   Zpandas._libsr   r   r   Zpandas._libs.tslibsr   r	   r
   r   r   Zpandas._libs.tslibs.parsingr   r   Zpandas._typingr   r   Zpandas.errorsr   Zpandas.util._decoratorsr   Zpandas.core.dtypes.commonr   r   r   r   Zpandas.core.dtypes.dtypesr   Zpandas.core.dtypes.missingr   Zpandas.core.arrays.periodr   r   r   r   Zpandas.core.commoncorecommonr   Zpandas.core.indexes.baseZindexesrZ   Zibaser   Z pandas.core.indexes.datetimeliker   Zpandas.core.indexes.datetimesr   r    Zpandas.core.indexes.extensionr!   Zpandas.core.indexes.numericr"   dictZ_index_doc_kwargsupdater   r0   Z
_field_opsr4   r   r.   r.   r.   r/   <module>   sV   
    V         