U
    f/eO                     @  s  d dl mZ d dlmZ d dlZd dlmZmZmZm	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mZmZmZ d dl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&m'Z' d dl(m)Z)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@mAZA d dlBmC  mDZE d dlFmGZH d dlImC  mJZK erd dlFmLZL ddiZMd1ddddZNG dd deHjOZPdd ZQd2ddddd d!d"ZRd#d$ ZSd3d%d&Zd4d(d)ZTd5d*d+d,d-ZUd.d+d/d0ZVdS )6    )annotations)	timedeltaN)TYPE_CHECKINGAnyCallableSequence)NDArrayBacked)

BaseOffsetNaTNaTType	Timedeltadelta_to_nanosecondsdt64arr_to_periodarriNaTparsingperiod	to_offset)	FreqGroup)isleapyear_arr)Tickdelta_to_tick)DIFFERENT_FREQIncompatibleFrequencyPeriodget_period_field_arrperiod_asfreq_arr)AnyArrayLikeDtypeNpDtype)cache_readonlydoc)TD64NS_DTYPEensure_objectis_datetime64_dtypeis_dtype_equalis_float_dtypeis_integer_dtypeis_period_dtypepandas_dtype)PeriodDtype)ABCIndexABCPeriodIndex	ABCSeriesABCTimedeltaArray)isnanotna)datetimelikeDatetimeArrayklassPeriodArraystrnamec                   s     fdd} |_ ||_t|S )Nc                   s   | j j}t | j|}|S N)freq_period_dtype_coder   asi8)selfbaseresultr6    =/tmp/pip-unpacked-wheel-tiezk1ph/pandas/core/arrays/period.pyfU   s    z_field_accessor.<locals>.f)__name____doc__property)r7   Z	docstringrA   r?   r6   r@   _field_accessorT   s    rE   c                      s  e Zd ZU dZdZdZeZefZe	Z
dZg Zded< dgZded< d	d
dgZded< dddddddddddddddddgZded< ee e Zded< d d!d"gZded#< d$ed%< dd(d)d*d+d,Zedd-d.d(d d/d0d1Zed&d'd*d2d3d(d)d d4d5d6Zed&d'd*d(d)d d7d8d9Zedd d:d;d<Zed=d> Zdd?d)d@dAdBdCZdDdEdFdGdHZdd)dIdJdKZed$d:dLdMZedNd:dOdPZ ddQd-dRdSdTZ!ddUdVZ"e#ddWZ$e#ddXZ%e#ddYZ&e#ddZZ'e#dd[Z(e#dd\Z)e#dd]Z*e*Z+e#dd^Z,e,Z-e-Z.e#dd_ Z/Z0e#dd`Z1e#dZ2e#ddaZ3e3Z4ed-d:dbdcZ5ddDdedfdgdhZ6ddid djdkdlZ7d?d:dmdnZ8e9f e:dododpddDd dfdrdsZ;dd)dtdudvZ<e=j>dd-d:dxdyZ?dd)d{ fd|d}Z@dd-d:ddZAdd d: fddZBdd ZCdd ZDdd ZEd-dd dddZFdNd fddZG fddZHdd ZIdd ZJdid:ddZKeded:ddZLeded:ddZMdd)ddddZN  ZOS )r4   a)  
    Pandas ExtensionArray for storing Period data.

    Users should use :func:`~pandas.period_array` to create new instances.
    Alternatively, :func:`~pandas.array` can be used to create new instances
    from a sequence of Period scalars.

    Parameters
    ----------
    values : Union[PeriodArray, Series[period], ndarray[int], PeriodIndex]
        The data to store. These should be arrays that can be directly
        converted to ordinals without inference or copy (PeriodArray,
        ndarray[int64]), or a box around such an array (Series[period],
        PeriodIndex).
    dtype : PeriodDtype, optional
        A PeriodDtype instance from which to extract a `freq`. If both
        `freq` and `dtype` are specified, then the frequencies must match.
    freq : str or DateOffset
        The `freq` to use for the array. Mostly applicable when `values`
        is an ndarray of integers, when `freq` is required. When `values`
        is a PeriodArray (or box around), it's checked that ``values.freq``
        matches `freq`.
    copy : bool, default False
        Whether to copy the ordinals before storing.

    Attributes
    ----------
    None

    Methods
    -------
    None

    See Also
    --------
    Period: Represents a period of time.
    PeriodIndex : Immutable Index for period data.
    period_range: Create a fixed-frequency PeriodArray.
    array: Construct a pandas array.

    Notes
    -----
    There are two components to a PeriodArray

    - ordinals : integer ndarray
    - freq : pd.tseries.offsets.Offset

    The values are physically stored as a 1-D ndarray of integers. These are
    called "ordinals" and represent some kind of offset from a base.

    The `freq` indicates the span covered by each element of the array.
    All elements in the PeriodArray have the same `freq`.
    i  Zperiodarray)r   z	list[str]
_other_opsis_leap_year	_bool_ops
start_timeend_timer9   _object_opsyearmonthdayhourminutesecond
weekofyearweekdayweek	dayofweekday_of_week	dayofyearday_of_yearquarterqyeardays_in_monthdaysinmonth
_field_ops_datetimelike_opsstrftimeto_timestampasfreq_datetimelike_methodsr)   _dtypeNFzDtype | Nonebooldtypecopyc                 C  s   t ||}|d k	rt|}t|trD|j}t|t| sTtdnt|trT|j}t|t| r|d k	r~||j	kr~t
|||j|j	 }}tj|d|d}|d krtdt| |t| d S )NzIncorrect dtypeint64re   z,freq is not specified and cannot be inferred)validate_dtype_freqr   _maybe_convert_freq
isinstancer,   _valuestype	TypeErrorr+   r9   raise_on_incompatible_ndarraynparray
ValueErrorr   __init__r)   )r<   valuesrf   r9   rg   r?   r?   r@   rt      s"    





zPeriodArray.__init__z
np.ndarrayzBaseOffset | None)ru   r9   rf   returnc                 C  s0   d}t |tjr|jdks"t|| |||dS )Nz Should be numpy array of type i8i8)r9   rf   )rk   rq   ndarrayrf   AssertionError)clsru   r9   rf   Zassertion_msgr?   r?   r@   _simple_new   s    zPeriodArray._simple_newztype[PeriodArray]z&Sequence[Period | None] | AnyArrayLike)rz   scalarsrf   rg   rv   c                C  st   |rt |tr|j}nd }t || r@t|j| |r<| }|S tj|td}|pZt	
|}t	||}| ||dS )Nrf   r9   )rk   r)   r9   ri   rf   rg   rq   asarrayobject	libperiodZextract_freqZextract_ordinals)rz   r|   rf   rg   r9   periodsordinalsr?   r?   r@   _from_sequence   s    
zPeriodArray._from_sequence)rf   rg   rv   c                C  s   | j |||dS )Nre   )r   )rz   stringsrf   rg   r?   r?   r@   _from_sequence_of_strings   s    z%PeriodArray._from_sequence_of_stringsrv   c                 C  s   t |||\}}| ||dS )a  
        Construct a PeriodArray from a datetime64 array

        Parameters
        ----------
        data : ndarray[datetime64[ns], datetime64[ns, tz]]
        freq : str or Tick
        tz : tzinfo, optional

        Returns
        -------
        PeriodArray[freq]
        r~   )r   )rz   datar9   tzr?   r?   r@   _from_datetime64  s    zPeriodArray._from_datetime64c                 C  s   t |}|d k	rt|}t|}|d k	s4|d k	rX|dkrDtdt||||\}}n(|dkrxtf d|i|\}}ntd||fS )Nr   z=Can either instantiate from fields or endpoints, but not bothr9   z/Not enough parameters to construct Period range)dtlZvalidate_periodsr   rj   lenrs   _get_ordinal_range_range_from_fields)rz   startendr   r9   fieldsZfield_countZsubarrr?   r?   r@   _generate_range  s    

zPeriodArray._generate_rangezPeriod | NaTTypeznp.int64)valuesetitemrv   c                 C  sN   |t krt|jS t|| jr:| j||d t|jS td| dd S )Nr   z!'value' should be a Period. Got 'z
' instead.)	r
   rq   rh   r   rk   _scalar_type_check_compatible_withordinalrs   )r<   r   r   r?   r?   r@   _unbox_scalar0  s    zPeriodArray._unbox_scalarr5   r   )r   rv   c                 C  s   t || jdS )Nr~   )r   r9   )r<   r   r?   r?   r@   _scalar_from_string>  s    zPeriodArray._scalar_from_stringr   c                 C  s   |t krd S | | d S r8   )r
   _require_matching_freq)r<   otherr   r?   r?   r@   r   A  s    z"PeriodArray._check_compatible_withc                 C  s   | j S r8   )rc   r<   r?   r?   r@   rf   I  s    zPeriodArray.dtyper	   c                 C  s   | j jS )zC
        Return the frequency object for this PeriodArray.
        rf   r9   r   r?   r?   r@   r9   N  s    zPeriodArray.freqzNpDtype | None)rf   rv   c                 C  s0   |dkr| j S |tkr| j S tjt| tdS )Nrw   r}   )r;   rd   _isnanrq   rr   listr   )r<   rf   r?   r?   r@   	__array__U  s
    zPeriodArray.__array__c                 C  s   ddl }ddlm} |dk	r|j|r>|j| j|  |dS t||rp| j	|j
krtd| j	 d|j
 dntd| d	|| j	}|j| j|  d
d}|j||S )z6
        Convert myself into a pyarrow Array.
        r   N)ArrowPeriodType)maskrm   zENot supported to convert PeriodArray to array with different 'freq' (z vs )z)Not supported to convert PeriodArray to 'z' typerh   )pyarrowZpandas.core.arrays._arrow_utilsr   types
is_integerrr   rp   r.   rk   freqstrr9   rn   ZExtensionArrayZfrom_storage)r<   rm   r   r   Zperiod_typeZstorage_arrayr?   r?   r@   __arrow_array__`  s     


zPeriodArray.__arrow_array__z)
        The year of the period.
        z6
        The month as January=1, December=12.
        z)
        The days of the period.
        z)
        The hour of the period.
        z+
        The minute of the period.
        z+
        The second of the period.
        z/
        The week ordinal of the year.
        z>
        The day of the week with Monday=0, Sunday=6.
        z.
        The ordinal day of the year.
        z*
        The quarter of the date.
        z2
        The number of days in the month.
        c                 C  s   t t| jS )zH
        Logical indicating if the date belongs to a leap year.
        )r   rq   r   rL   r   r?   r?   r@   rG     s    zPeriodArray.is_leap_yearr   r2   )howrv   c           	      C  s   ddl m} t|}|dk}|rx|dks4| jdkrXtddtdd }| jdd	| S tdd}| | j jdd	| S |d
kr|  }|}nt	|}|j
}| j||d	}t|j|}||dS )a  
        Cast to DatetimeArray/Index.

        Parameters
        ----------
        freq : str or DateOffset, optional
            Target frequency. The default is 'D' for week or longer,
            'S' otherwise.
        how : {'s', 'e', 'start', 'end'}
            Whether to use the start or end of the time period being converted.

        Returns
        -------
        DatetimeArray/Index
        r   r1   EB   Dnsr   r   NZinfer)pandas.core.arraysr2   r   validate_end_aliasr9   r   r`   _get_to_timestamp_baser   rj   r:   ra   Zperiodarr_to_dt64arrr;   Z
_with_freq)	r<   r9   r   r2   r   adjustr=   Znew_parrnew_datar?   r?   r@   r`     s"    


zPeriodArray.to_timestampint)r   rv   c                 C  sR   |dk	rt dt| j d| j|| jj  }| jr@t|| j< t| || jdS )a  
        Shift each value by `periods`.

        Note this is different from ExtensionArray.shift, which
        shifts the *position* of each element, padding the end with
        missing values.

        Parameters
        ----------
        periods : int
            Number of periods to shift by.
        freq : pandas.DateOffset, pandas.Timedelta, or str
            Frequency increment to shift by.
        Nz%`freq` argument is not supported for z._time_shiftr~   )	rn   rm   rB   r;   r9   n_hasnansr   r   )r<   r   r9   ru   r?   r?   r@   _time_shift  s    
zPeriodArray._time_shiftc                 C  s   t j|| jdS )N)r   r9   )r   Z_from_ordinalr9   )r<   xr?   r?   r@   	_box_func  s    zPeriodArray._box_funcZPeriodIndex)r   Z
other_namer   c           	      C  sx   t |}t|}| jj}|j}| j}|dk}|rF|| jj d }n|}t||||}| j	rht
|| j< t| ||dS )a  
        Convert the {klass} to the specified frequency `freq`.

        Equivalent to applying :meth:`pandas.Period.asfreq` with the given arguments
        to each :class:`~pandas.Period` in this {klass}.

        Parameters
        ----------
        freq : str
            A frequency.
        how : str {{'E', 'S'}}, default 'E'
            Whether the elements should be aligned to the end
            or start within pa period.

            * 'E', 'END', or 'FINISH' for end,
            * 'S', 'START', or 'BEGIN' for start.

            January 31st ('END') vs. January 1st ('START') for example.

        Returns
        -------
        {klass}
            The transformed {klass} with the new frequency.

        See Also
        --------
        {other}.asfreq: Convert each Period in a {other_name} to the given frequency.
        Period.asfreq : Convert a :class:`~pandas.Period` object to the given frequency.

        Examples
        --------
        >>> pidx = pd.period_range('2010-01-01', '2015-01-01', freq='A')
        >>> pidx
        PeriodIndex(['2010', '2011', '2012', '2013', '2014', '2015'],
        dtype='period[A-DEC]')

        >>> pidx.asfreq('M')
        PeriodIndex(['2010-12', '2011-12', '2012-12', '2013-12', '2014-12',
        '2015-12'], dtype='period[M]')

        >>> pidx.asfreq('M', how='S')
        PeriodIndex(['2010-01', '2011-01', '2012-01', '2013-01', '2014-01',
        '2015-01'], dtype='period[M]')
        r   r   r~   )r   r   r   rj   r9   r:   r;   r   r   r   r   r   rm   )	r<   r9   r   Zbase1Zbase2r;   r   r   r   r?   r?   r@   ra     s    .


zPeriodArray.asfreq)boxedc                 C  s   |rt S djS )Nz'{}')r5   format)r<   r   r?   r?   r@   
_formatter\  s    zPeriodArray._formatterr
   c                   s|   |  t} r fddndd | jr`| j}|||< | }tfdd|| D ||< ntfdd|D }|S )z3
        actually format my specific types
        c                   s
   |   S r8   )r_   dt)date_formatr?   r@   <lambda>k      z2PeriodArray._format_native_types.<locals>.<lambda>c                 S  s   t | S r8   )r5   r   r?   r?   r@   r   m  r   c                   s   g | ]} |qS r?   r?   .0r   	formatterr?   r@   
<listcomp>s  s     z4PeriodArray._format_native_types.<locals>.<listcomp>c                   s   g | ]} |qS r?   r?   r   r   r?   r@   r   u  s     )astyper   r   r   rq   rr   )r<   Zna_repr   kwargsru   r   Zimaskr?   )r   r   r@   _format_native_typesa  s    
"z PeriodArray._format_native_typesTrg   c                   sH   t |}t|| jr$|s| S |  S t|r8| |jS t j||dS )Nr   )	r(   r$   rc   rg   r'   ra   r9   superr   )r<   rf   rg   	__class__r?   r@   r   z  s    zPeriodArray.astypeleftc                 C  s,   |  |d}| jd}|j|||dS )NM8[ns])sidesorter)Z_validate_searchsorted_valueviewrp   searchsorted)r<   r   r   r   Zm8arrr?   r?   r@   r     s    zPeriodArray.searchsortedc                   s@   |d k	r.|  d}|j|||d}| | jS t j|||dS )Nr   )r   methodlimit)r   fillnarf   r   )r<   r   r   r   Zdtar>   r   r?   r@   r     s
    
zPeriodArray.fillnac                 C  s   |t k	sttS r8   )r
   ry   NotImplementedr<   r   r?   r?   r@   _sub_datelike  s    zPeriodArray._sub_datelikec                   sF     |  j}||j }t fdd|D } jrBt| j< |S )Nc                   s   g | ]} j | qS r?   r~   r   r   r   r?   r@   r     s     z+PeriodArray._sub_period.<locals>.<listcomp>)r   r;   r   rq   rr   r   r
   r   )r<   r   r;   r   r?   r   r@   _sub_period  s    


zPeriodArray._sub_periodc                   sb     | tj j|j  j|jd}t fdd|D } jsJ|jr^ j|jB }t||< |S )a  
        Subtract a Period Array/Index from self.  This is only valid if self
        is itself a Period Array/Index, raises otherwise.  Both objects must
        have the same frequency.

        Parameters
        ----------
        other : PeriodIndex or PeriodArray

        Returns
        -------
        result : np.ndarray[object]
            Array of DateOffset objects; nulls represented by NaT.
        )arr_maskZb_maskc                   s   g | ]} j j| qS r?   )r9   r=   r   r   r?   r@   r     s     z1PeriodArray._sub_period_array.<locals>.<listcomp>)	r   algoschecked_add_with_arrr;   r   rq   rr   r   r
   )r<   r   Z
new_valuesr   r?   r   r@   _sub_period_array  s    
   zPeriodArray._sub_period_arrayzCallable[[Any, Any], Any])r   oprv   c                 C  sd   |t jt jfkst|t jkr$| }tj| j|| jd}|d}t	
|| jt t| || jdS )a%  
        Add or subtract array of integers; equivalent to applying
        `_time_shift` pointwise.

        Parameters
        ----------
        other : np.ndarray[integer-dtype]
        op : {operator.add, operator.sub}

        Returns
        -------
        result : PeriodArray
        )r   rw   r~   )operatoraddsubry   r   r   r;   r   r   rq   Zputmaskr   rm   r9   )r<   r   r   Z
res_valuesr?   r?   r@   _addsub_int_array  s    

zPeriodArray._addsub_int_array)r   c                   s<   t |trt| j|dd t |j}t| || jdS )NT)r=   r~   )	rk   r   ry   r   r   _add_timedeltalike_scalarr   rm   r9   )r<   r   r>   r   r?   r@   _add_offset  s    zPeriodArray._add_offsetc                   s4   t | jtst| |t|r(| |}t |S )z
        Parameters
        ----------
        other : timedelta, Tick, np.timedelta64

        Returns
        -------
        PeriodArray
        )rk   r9   r   ro   r/    _check_timedeltalike_freq_compatr   r   r   r   r?   r@   r     s
    


z%PeriodArray._add_timedeltalike_scalarc                 C  sf   t | jtstd| j tt|s6| |}n| t	d S | 
|tjj}t| || jdS )z
        Parameters
        ----------
        other : TimedeltaArray or ndarray[timedelta64]

        Returns
        -------
        result : ndarray[int64]
        z2Cannot add or subtract timedelta64[ns] dtype from r
   r}   )rk   r9   r   rn   rf   rq   allr.   r   timedelta64r   r   r   r;   rm   )r<   r   deltar   r?   r?   r@   _add_timedelta_arraylike   s    

z$PeriodArray._add_timedelta_arraylikec                 C  s   t | jtst| jjj}t |ttjtfr6t	|}nBt |tj
rr|jjdksRt|jtkrf|t}|d}n|j}t|| dkr|| }|S t| |dS )a<  
        Arithmetic operations with timedelta-like scalars or array `other`
        are only valid if `other` is an integer multiple of `self.freq`.
        If the operation is valid, find that integer multiple.  Otherwise,
        raise because the operation is invalid.

        Parameters
        ----------
        other : timedelta, np.timedelta64, Tick,
                ndarray[timedelta64], TimedeltaArray, TimedeltaIndex

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

        Raises
        ------
        IncompatibleFrequency
        mrw   r   N)rk   r9   r   ry   r=   nanosr   rq   r   r   rx   rf   kindr!   r   r   r;   r   ro   )r<   r   Z
base_nanosr   r   r?   r?   r@   r     s    



z,PeriodArray._check_timedeltalike_freq_compatc                 C  sH   | j j}|tjjk rtjjS tjj|  kr8tjjkrDn ntjjS |S )a  
        Return frequency code group used for base of to_timestamp against
        frequency code.

        Return day freq code against longer freq than day.
        Return second freq code against hour between second.

        Returns
        -------
        int
        )rc   Z_dtype_coder   ZFR_BUSr   ZFR_DAYZFR_HRZFR_SEC)r<   r=   r?   r?   r@   r   L  s     z"PeriodArray._get_to_timestamp_basec                 C  s   | j ddS )Nr   r   r`   r   r?   r?   r@   rI   _  s    zPeriodArray.start_timec                 C  s   | j ddS )Nr   r   r   r   r?   r?   r@   rJ   c  s    zPeriodArray.end_timeNone)r=   rv   c                 C  s^   t |tr|}n|j}|r*| jj|jk}n
| j|k}|rZtjt| j| j|jd}t	|d S )Nrz   Zown_freq
other_freq)
rk   r	   r9   r=   r   r   rm   rB   r   r   )r<   r   r=   r   	conditionmsgr?   r?   r@   r   g  s    

z"PeriodArray._require_matching_freq)NNF)NN)N)F)F)N)N)Nr   )N)Nr   )F)r
   N)T)r   N)NNN)F)PrB   
__module____qualname__rC   Z__array_priority__Z_typr   r   Z_recognized_scalarsr'   Z_is_recognized_dtypeZ_infer_matchesrF   __annotations__rH   rK   r]   r^   rb   rt   classmethodr{   r   r   r   r   r   r   r   r   rf   rD   r9   r   r   rE   rL   rM   rN   rO   rP   rQ   rR   rT   rV   rU   rS   rW   rX   rY   rZ   r[   r\   rG   r`   r   r   r    _shared_doc_kwargsra   r   r   Zravel_compatr   r   r   r   r   r   r   r   r   r   r   r   r   rI   rJ   r   __classcell__r?   r?   r   r@   r4   _   s  
7        
 
,F   3c                 C  sf   t |tjtfs|dkrd}n(t |ttttfr8|j}nt	t
|j}tjt| j| j|d}t|S )a>  
    Helper function to render a consistent error message when raising
    IncompatibleFrequency.

    Parameters
    ----------
    left : PeriodArray
    right : None, DateOffset, Period, ndarray, or timedelta-like

    Returns
    -------
    IncompatibleFrequency
        Exception to be raised by the caller.
    Nr   )rk   rq   rx   r-   r+   r4   r   r	   r   r   r   r   r   rm   rB   r   )r   rightr   r   r?   r?   r@   ro   |  s      ro   Fz,Sequence[Period | str | None] | AnyArrayLikezstr | Tick | Nonerd   )r   r9   rg   rv   c                 C  s   t | dd}t|r t| |S t|r4t| |dS t| tjtt	t
fsPt| } t| }|rht|}nd}t|rt|dkrtdt|jr|jtjdd}t||}t||dS t|} tj| |dS )	a  
    Construct a new PeriodArray from a sequence of Period scalars.

    Parameters
    ----------
    data : Sequence of Period objects
        A sequence of Period objects. These are required to all have
        the same ``freq.`` Missing values can be indicated by ``None``
        or ``pandas.NaT``.
    freq : str, Tick, or Offset
        The frequency of every element of the array. This can be specified
        to avoid inferring the `freq` from `data`.
    copy : bool, default False
        Whether to ensure a copy of the data is made.

    Returns
    -------
    PeriodArray

    See Also
    --------
    PeriodArray
    pandas.PeriodIndex

    Examples
    --------
    >>> period_array([pd.Period('2017', freq='A'),
    ...               pd.Period('2018', freq='A')])
    <PeriodArray>
    ['2017', '2018']
    Length: 2, dtype: period[A-DEC]

    >>> period_array([pd.Period('2017', freq='A'),
    ...               pd.Period('2018', freq='A'),
    ...               pd.NaT])
    <PeriodArray>
    ['2017', '2018', 'NaT']
    Length: 3, dtype: period[A-DEC]

    Integers that look like years are handled

    >>> period_array([2000, 2001, 2002], freq='D')
    <PeriodArray>
    ['2000-01-01', '2001-01-01', '2002-01-01']
    Length: 3, dtype: period[D]

    Datetime-like strings may also be passed

    >>> period_array(['2000-Q1', '2000-Q2', '2000-Q3', '2000-Q4'], freq='Q')
    <PeriodArray>
    ['2000Q1', '2000Q2', '2000Q3', '2000Q4']
    Length: 4, dtype: period[Q-DEC]
    rf   Nr~   r   z9PeriodIndex does not allow floating point in constructionFr   r}   )getattrr#   r4   r   r'   rk   rq   rx   r   tupler,   r   r)   r%   r   rn   r&   rf   r   rh   r   Zfrom_ordinalsr"   r   )r   r9   rg   Z
data_dtypeZarrdatarf   Zarrr   r?   r?   r@   period_array  s&    :


r   c                 C  sV   |dk	rt |}| dk	rRt| } t| s0td|dkr@| j}n|| jkrRtd|S )at  
    If both a dtype and a freq are available, ensure they match.  If only
    dtype is available, extract the implied freq.

    Parameters
    ----------
    dtype : dtype
    freq : DateOffset or None

    Returns
    -------
    freq : DateOffset

    Raises
    ------
    ValueError : non-period dtype
    IncompatibleFrequency : mismatch between dtype and freq
    Nzdtype must be PeriodDtypez&specified freq and dtype are different)r   r(   r'   rs   r9   r   r   r?   r?   r@   ri     s    
ri   c                 C  s   | j t dkr td| j  |dkr^t| trB| j| j } }qrt| trr| j| jj } }nt| ttfrr| j} t	
|}|j}t| d|||fS )a  
    Convert an datetime-like array to values Period ordinals.

    Parameters
    ----------
    data : Union[Series[datetime64[ns]], DatetimeIndex, ndarray[datetime64ns]]
    freq : Optional[Union[str, Tick]]
        Must match the `freq` on the `data` if `data` is a DatetimeIndex
        or Series.
    tz : Optional[tzinfo]

    Returns
    -------
    ordinals : ndarray[int64]
    freq : Tick
        The frequency extracted from the Series or DatetimeIndex if that's
        used.

    r   zWrong dtype: Nrw   )rf   rq   rs   rk   r*   rl   r9   r,   r   r   rj   r:   c_dt64arr_to_periodarrr   )r   r9   r   r=   r?   r?   r@   r     s    


r   r   c                 C  sH  t | ||dkrtd|d k	r0t|}|j}| d k	rBt| |} |d k	rTt||}t| t}t|t}|r|r| j|jkrtd| tks|tkrtd|d kr|r| j}n|r|j}ntd|d k	r$|| }| d krt	j
|j| | |jd |t	jd}nt	j
| j| j| |t	jd}nt	j
| j|jd |t	jd}||fS )N   zOOf the three parameters: start, end, and periods, exactly two must be specifiedz!start and end must have same freqzstart and end must not be NaTz#Could not infer freq from start/endr   r}   )comZcount_not_noners   r   r   r   rk   r9   r
   rq   Zaranger   rh   )r   r   r   r9   ZmultZis_start_perZ
is_end_perr   r?   r?   r@   r   =  sP    





      r   ztuple[np.ndarray, BaseOffset]r   c                 C  sP  |d krd}|d krd}|d kr$d}|d kr0d}g }|d k	r|d krVt d}tjj}	n&t |}t|}	|	tjjkr|td|j}
t| |\} }t	| |D ]>\}}t
|||
\}}t||dddddd|		}|| qn`t |}t|}	t| |||||}t	| D ]2\}}}}}}|t||||||dd|		 qtj|tjd|fS )Nr   r   Qzbase must equal FR_QTRr}   )r   r   ZFR_QTRr   r   Zfreq_to_dtype_codery   r   _make_field_arrayszipr   Zquarter_to_myearZperiod_ordinalappendrq   rr   rh   )rL   rM   rY   rN   rO   rP   rQ   r9   r   r=   r   yqr   valZarraysZmthdhmnsr?   r?   r@   r   m  s:    



$r   zlist[np.ndarray]c                    s`   d  | D ]D}t |ttjtfr d k	r<t| kr<tdq d krt| q fdd| D S )NzMismatched Period array lengthsc                   s4   g | ],}t |tjttfr$t|n
t| qS r?   )rk   rq   rx   r   r,   r   repeatr   lengthr?   r@   r     s   z&_make_field_arrays.<locals>.<listcomp>)rk   r   rq   rx   r,   r   rs   )r   r   r?   r  r@   r    s    


r  )N)NF)N)r   )NNNNNNNN)W
__future__r   datetimer   r   typingr   r   r   r   Znumpyrq   Zpandas._libs.arraysr   Zpandas._libs.tslibsr	   r
   r   r   r   r   r  r   r   r   r   r   Zpandas._libs.tslibs.dtypesr   Zpandas._libs.tslibs.fieldsr   Zpandas._libs.tslibs.offsetsr   r   Zpandas._libs.tslibs.periodr   r   r   r   r   Zpandas._typingr   r   r   Zpandas.util._decoratorsr   r    Zpandas.core.dtypes.commonr!   r"   r#   r$   r%   r&   r'   r(   Zpandas.core.dtypes.dtypesr)   Zpandas.core.dtypes.genericr*   r+   r,   r-   Zpandas.core.dtypes.missingr.   r/   Zpandas.core.algorithmscoreZ
algorithmsr   r   r0   r   Zpandas.core.commoncommonr  r2   r   rE   ZDatelikeOpsr4   ro   r   ri   r   r   r  r?   r?   r?   r@   <module>   sb   0(
       ##  Z!
%
1        /