U
    MZfTD                     @  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m	Z
 d dlmZmZmZmZmZ d dlmZ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 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&  m*  m+Z, d dl)m-Z- d dl.m/Z/ d dl0m1Z1m2Z2 d dl3m4Z4 e5e,j6Z6e67ddi ddiZ8dd Z9e4dddge!j: e!dde4ddge!G dd  d e/Z;d%d!d d"d#d$Z<dS )&    )annotations)datetime	timedelta)HashableN)index)
BaseOffsetNaTPeriod
ResolutionTick)DtypeDtypeObjnpt)cache_readonlydoc)
is_integer)PeriodDtype)	ABCSeries)is_valid_na_for_dtype)PeriodArrayperiod_arrayraise_on_incompatiblevalidate_dtype_freq)maybe_extract_name)DatetimeIndexOpsMixin)DatetimeIndexIndex)inherit_namesZ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-nbcvw55c/pandas/core/indexes/period.py_new_PeriodIndex;   s    

r+   strftime
start_timeZend_timeT)wrapZis_leap_yearZ_format_native_typesc                      s  e Zd ZU dZdZded< ded< ded< eZd	Ze	d
dddZ
eddddZeejfdddedUdd dddZeejdVd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e	eejjddd"d#ZdWd%d&d'd d(d)d*Ze	d+dd,d-Zd.dd/d0Zd1d&d2d3d4Zdd5d+d6 fd7d8Ze	d&dd9d:Ze	ddd;d<Z fd=d>Zd?d@ ZdAdBdCdDdEZdFdAdGdHdIZee j!ddJ fdKdLZ!ddFdMdNdOZ"ee j#dXdQdRdSdTZ#  Z$S )Y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periodindexr   _datar   r!   r   r$   Tztype[libindex.PeriodEngine])returnc                 C  s   t jS N)libindexZPeriodEngineselfr)   r)   r*   _engine_type   s    zPeriodIndex._engine_typer
   c                 C  s   | j jS r2   )r$   _resolution_objr4   r)   r)   r*   r7      s    zPeriodIndex._resolution_objzpandas.arrays.PeriodArray)otherZ
other_nameNEstr)howr1   c                 C  s"   | j ||}t| j|| jdS Nname)r0   asfreqtyper%   r>   r5   r!   r;   Zarrr)   r)   r*   r?      s    zPeriodIndex.asfreqstartr   c                 C  s   | j ||}tj|| jdS r<   )r0   to_timestampr   r%   r>   rA   r)   r)   r*   rC      s    zPeriodIndex.to_timestampr   c                 C  s   t | jj| jdS r<   )r   r0   hourr>   r4   r)   r)   r*   rD      s    zPeriodIndex.hourc                 C  s   t | jj| jdS r<   )r   r0   minuter>   r4   r)   r)   r*   rE      s    zPeriodIndex.minutec                 C  s   t | jj| jdS r<   )r   r0   secondr>   r4   r)   r)   r*   rF      s    zPeriodIndex.secondFzDtype | Noneboolr   )r$   copyr>   r1   c                 K  s8  dddddddh}d }	|s.t |ttfr.|j}	t||s^tt|| d }
td	|
 t||| }|d kr|d kr|s| 	d  t
d d d ||\}}|}t
||d
}njt||}|rt || r|j|kr||}|d kr|d k	rtj|tjd}t
||d
}nt||d}|r(| }| j|||	dS )NyearmonthdayZquarterrD   rE   rF   r   z-__new__() got an unexpected keyword argument r"   r$   )r   r!   )r>   refs)
isinstancer   r   Z_referencessetissubsetlist	TypeErrorr   Z_raise_scalar_data_errorr   _generate_ranger   r!   r?   npasarrayr    r   rH   r%   )r&   r   Zordinalr!   r$   rH   r>   fieldsZvalid_field_setrM   argumentZfreq2r)   r)   r*   __new__   s>    



zPeriodIndex.__new__z
np.ndarrayc                 C  s   t j| tdS )NrL   )rT   rU   objectr4   r)   r)   r*   r(     s    zPeriodIndex.valueszint | npt.NDArray[np.int64]c                 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)rN   r   rT   Ztimedelta64r   Zndarrayr!   r0   Z _check_timedeltalike_freq_compatr   basenr   r   )r5   r8   deltar)   r)   r*   _maybe_convert_timedelta  s    
z$PeriodIndex._maybe_convert_timedeltar   )r$   r1   c                 C  s2   t |tsdS |j}| j}|j|jko0|j|jkS )zF
        Can we compare values of the given dtype to our own?
        F)rN   r   r!   _period_dtype_coder[   )r5   r$   r!   Zown_freqr)   r)   r*   _is_comparable_dtype6  s    

z PeriodIndex._is_comparable_dtypeznpt.NDArray[np.bool_])wheremaskr1   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)rN   r   r/   Z_valuesr!   rR   super	asof_locs)r5   r`   ra   	__class__r)   r*   rc   L  s
    

zPeriodIndex.asof_locsc                 C  sH   t | dkrdS | jstd| j}t|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   N   )lenZis_monotonic_increasing
ValueErrorZasi8rG   all)r5   r(   r)   r)   r*   is_fullY  s    zPeriodIndex.is_fullc                 C  s   dS )Nperiodr)   r4   r)   r)   r*   inferred_typef  s    zPeriodIndex.inferred_typec                   s(   t  ||}| j|jkr$| |}|S r2   )rb   _convert_tolerancer$   r]   )r5   Z	tolerancetargetrd   r)   r*   ro   o  s    
zPeriodIndex._convert_tolerancec              
   C  sP  |}|  | t|| jr t}nt|trz| |\}}W n4 tk
rp } ztd| d|W 5 d}~X Y nX | 	|rz| 
||W S  tk
r } zt||W 5 d}~X Y nX || jkr| |}nt|n6t|tr| | n t|tr| |}nt|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)Z_check_indexing_errorr   r$   r   rN   r:   Z_parse_with_resorj   KeyErrorZ_can_partial_date_sliceZ_partial_date_slicer7   _cast_partial_indexing_scalarr	   _disallow_mismatched_indexingr   r   get_loc)r5   keyZorig_keyparsedresoerrr)   r)   r*   rt   |  s4    

$



zPeriodIndex.get_locr	   None)ru   r1   c                 C  s0   | j }|j }|j|jkr$|j|jks,t|d S r2   )r!   r[   r^   rq   )r5   ru   ZsfreqZkfreqr)   r)   r*   rs     s    

z)PeriodIndex._disallow_mismatched_indexingr   )labelr1   c              
   C  sD   zt || jd}W n, tk
r> } zt||W 5 d }~X Y nX |S )Nr"   )r	   r!   rj   rq   )r5   rz   rm   rx   r)   r)   r*   rr     s
    z)PeriodIndex._cast_partial_indexing_scalar)sidec                   s"   t |tr| |}t ||S r2   )rN   r   rr   rb   _maybe_cast_slice_bound)r5   rz   r{   rd   r)   r*   r|     s    

z#PeriodIndex._maybe_cast_slice_bound)rw   rv   c                 C  s.   t ||jd}|j| jdd|j| jddfS )Nr"   rB   )r;   end)r	   Zattr_abbrevr?   r!   )r5   rw   rv   Zivr)   r)   r*   _parsed_string_to_bounds  s    z$PeriodIndex._parsed_string_to_boundsrf   int)periodsc                 C  s&   |d k	rt dt| j d| | S )Nz%`freq` argument is not supported for z.shift)rR   r@   __name__)r5   r   r!   r)   r)   r*   shift  s
    zPeriodIndex.shift)Nr9   )NrB   )NNNNFN)rf   N)%r   
__module____qualname____doc__Z_typ__annotations__r   Z	_data_clsZ!_supports_partial_string_indexingpropertyr6   r   r7   r   r?   _shared_doc_kwargsrC   rD   fgetrE   rF   rX   r(   r]   r_   rc   rl   rn   ro   rt   rs   rr   r   r|   r~   r   __classcell__r)   r)   rd   r*   r/   F   sp   
E


      E$>r/   z
int | None)r   r1   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]')
    rh   zOOf the three parameters: start, end, and periods, exactly two must be specifiedND)rV   r"   r=   )comZcount_not_nonerj   rN   r	   r   rS   r/   )rB   r}   r   r!   r>   r   r)   r)   r*   period_range  s    4r   )NNNNN)=
__future__r   r   r   typingr   ZnumpyrT   Zpandas._libsr   r3   Zpandas._libs.tslibsr   r   r	   r
   r   Zpandas._typingr   r   r   Zpandas.util._decoratorsr   r   Zpandas.core.dtypes.commonr   Zpandas.core.dtypes.dtypesr   Zpandas.core.dtypes.genericr   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   dictZ_index_doc_kwargsupdater   r+   Z
_field_opsr/   r   r)   r)   r)   r*   <module>   sP   
             