
    Pi              	         d 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ZddlmZ ddlmZmZmZ ddl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 ddl 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-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>c m?Z@ ddlAmBZB ddlCmDZDmEZEmFZF ddlGmHZHmIZI ddlJmKZKmLZL ddlMmNZN ddlOmPZPmQZQ erddlRmSZS ddlTmUZUmVZVmWZWmXZX d ZYd ZZd Z[ eLddge<d !           eLg d"e<           eLd#d$ge<d %           ed&           G d' d(eK                                                          Z\d2d+Z]d2d,Z^ ed&          	 	 	 	 	 	 d3d4d1            Z_dS )5zdefine the IntervalIndex    )annotations)lelt)TYPE_CHECKINGAnyLiteralSelfN)lib)IntervalIntervalMixinIntervalTree)
BaseOffsetPeriod	Timedelta	Timestamp	to_offset)InvalidIndexError)cache_readonly
set_module)rewrite_exception)find_common_typeinfer_dtype_from_scalarmaybe_box_datetimelikemaybe_downcast_numericmaybe_unbox_numpy_scalarmaybe_upcast_numeric_to_64bit)
ensure_platform_intis_float_dtype
is_integeris_integer_dtypeis_list_like	is_numberis_object_dtype	is_scalaris_string_dtypepandas_dtype)DatetimeTZDtypeIntervalDtype)is_valid_na_for_dtypeunique)validate_periods)IntervalArray)is_valid_positional_slice)Indexensure_indexmaybe_extract_name)DatetimeIndex
date_range)ExtensionIndexinherit_names)
MultiIndex)TimedeltaIndextimedelta_range)Hashable)DtypeDtypeObjIntervalClosedTypenptc                   t          | dt          |                     }t          | t          t          f          rd}t          |          }t          j        |d          st          |t                    r| t          j
        dd          z   S t          |          r| dz   S t          |          rt          j        | t          j                  S t          dt          |                     Ndtypezdatetime64[ns]mM   nsz%cannot determine next label for type getattrtype
isinstancer   r   r&   r
   is_np_dtyper'   nptimedelta64r    r   	nextafterinf	TypeErrorlabelr@   s     p/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/pandas/core/indexes/interval.py_get_next_labelrQ   e   s    E7DKK00E%)Y/00 ! E
ud## Qz%'I'I Qr~a....	%	 	  Qqy			 Q|E26***OUOOPPP    c                   t          | dt          |                     }t          | t          t          f          rd}t          |          }t          j        |d          st          |t                    r| t          j
        dd          z
  S t          |          r| dz
  S t          |          r t          j        | t          j                   S t          dt          |                     r?   rD   rN   s     rP   _get_prev_labelrT   v   s    E7DKK00E%)Y/00 ! E
ud## Qz%'I'I Qr~a....	%	 	  Qqy			 Q|EBF7+++OUOOPPPrR   c                     | j         di |S )zv
    This is called upon unpickling, rather than the default which doesn't have
    arguments and breaks __new__.
     )from_arrays)clsds     rP   _new_IntervalIndexrZ      s    
 3?QrR   
set_closed	to_tuplesT)wrap)	__array__overlapscontainsclosed_leftclosed_right	open_left
open_rightis_emptyis_non_overlapping_monotonicclosed)cachepandasc                      e Zd ZU dZdZded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   dZeZ	 	 	 	 	 d^d_dZ	e
	 	 	 	 d`dad            Ze
	 	 	 	 d`dbd            Ze
	 	 	 	 d`dbd            Zedcd!            Zddd$Zded'Zedfd)            Zd* Zedgd,            Zdhdid/Zedjd0            Zedjd1            Zedjd2            Zdjd3Zd4 Zdkdld8Zdmd:Z	 	 	 dndodDZdpdFZdqdGZ dpdHZ!edjdI            Z"dJZ#dr fdMZ$edjdN            Z%dsdOZ&dtdQZ'edudR            Z(edudS            Z)edudT            Z*edudU            Z+dhdvdWZ,dwdYZ-dwdZZ.dxd\Z/d] Z0 xZ1S )yIntervalIndexa	  
    Immutable index of intervals that are closed on the same side.

    Parameters
    ----------
    data : array-like (1-dimensional)
        Array-like (ndarray, :class:`DateTimeArray`, :class:`TimeDeltaArray`) containing
        Interval objects from which to build the IntervalIndex.
    closed : {'left', 'right', 'both', 'neither'}, default 'right'
        Whether the intervals are closed on the left-side, right-side, both or
        neither.
    dtype : dtype or None, default None
        If None, dtype will be inferred.
    copy : bool, default None
        Whether to copy input data, only relevant for array, Series, and Index
        inputs (for other input, e.g. a list, a new array is created anyway).
        Defaults to True for array input and False for Index/Series.
        Set to False to avoid copying array input at your own risk (if you
        know the input data won't be modified elsewhere).
        Set to True to force copying Series/Index input up front.
    name : object, optional
         Name to be stored in the index.
    verify_integrity : bool, default True
        Verify that the IntervalIndex is valid.

    Attributes
    ----------
    left
    right
    closed
    mid
    length
    is_empty
    is_non_overlapping_monotonic
    is_overlapping
    values

    Methods
    -------
    from_arrays
    from_tuples
    from_breaks
    contains
    overlaps
    set_closed
    to_tuples

    See Also
    --------
    Index : The base pandas Index type.
    Interval : A bounded slice-like interval; the elements of an IntervalIndex.
    interval_range : Function to create a fixed frequency IntervalIndex.
    cut : Bin values into discrete Intervals.
    qcut : Bin values into equal-sized Intervals based on rank or sample quantiles.

    Notes
    -----
    See the `user guide
    <https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html#intervalindex>`__
    for more.

    Examples
    --------
    A new ``IntervalIndex`` is typically constructed using
    :func:`interval_range`:

    >>> pd.interval_range(start=0, end=5)
    IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]],
                  dtype='interval[int64, right]')

    It may also be constructed using one of the constructor
    methods: :meth:`IntervalIndex.from_arrays`,
    :meth:`IntervalIndex.from_breaks`, and :meth:`IntervalIndex.from_tuples`.

    See further examples in the doc strings of ``interval_range`` and the
    mentioned constructor methods.
    intervalindexr<   rg   boolrf   ra   rb   rc   rd   r-   _data_valuesFNTIntervalClosedType | Noner@   Dtype | Nonecopybool | NonenameHashable | Noneverify_integrityreturnr	   c                   t          |||           }|                     |||          \  }}t          d| j                  5  t	          |||||          }d d d            n# 1 swxY w Y   |                     ||          S )Nr-   )rg   rr   r@   rv   )r1   _maybe_copy_array_inputr   __name__r-   _simple_new)rX   datarg   r@   rr   rt   rv   arrays           rP   __new__zIntervalIndex.__new__   s     "$c22 00tUCC
d== 	 	!!1  E	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ud+++s   A""A&)A&rightc                    t          d| j                  5  t          j        ||||          }ddd           n# 1 swxY w Y   |                     ||          S )a\  
        Construct an IntervalIndex from an array of splits.

        Parameters
        ----------
        breaks : array-like (1-dimensional)
            Left and right bounds for each interval.
        closed : {'left', 'right', 'both', 'neither'}, default 'right'
            Whether the intervals are closed on the left-side, right-side, both
            or neither.
        name : str, optional
            Name of the resulting IntervalIndex.
        copy : bool, default False
            Copy the data.
        dtype : dtype or None, default None
            If None, dtype will be inferred.

        Returns
        -------
        IntervalIndex

        See Also
        --------
        interval_range : Function to create a fixed frequency IntervalIndex.
        IntervalIndex.from_arrays : Construct from a left and right array.
        IntervalIndex.from_tuples : Construct from a sequence of tuples.

        Examples
        --------
        >>> pd.IntervalIndex.from_breaks([0, 1, 2, 3])
        IntervalIndex([(0, 1], (1, 2], (2, 3]],
                      dtype='interval[int64, right]')
        r-   rg   rr   r@   Nrt   )r   rz   r-   from_breaksr{   )rX   breaksrg   rt   rr   r@   r}   s          rP   r   zIntervalIndex.from_breaks  s    T == 	 	!-vD  E	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 u4000   ;??c                    t          d| j                  5  t          j        |||||          }ddd           n# 1 swxY w Y   |                     ||          S )aH  
        Construct from two arrays defining the left and right bounds.

        Parameters
        ----------
        left : array-like (1-dimensional)
            Left bounds for each interval.
        right : array-like (1-dimensional)
            Right bounds for each interval.
        closed : {'left', 'right', 'both', 'neither'}, default 'right'
            Whether the intervals are closed on the left-side, right-side, both
            or neither.
        name : str, optional
            Name of the resulting IntervalIndex.
        copy : bool, default False
            Copy the data.
        dtype : dtype, optional
            If None, dtype will be inferred.

        Returns
        -------
        IntervalIndex

        Raises
        ------
        ValueError
            When a value is missing in only one of `left` or `right`.
            When a value in `left` is greater than the corresponding value
            in `right`.

        See Also
        --------
        interval_range : Function to create a fixed frequency IntervalIndex.
        IntervalIndex.from_breaks : Construct an IntervalIndex from an array of
            splits.
        IntervalIndex.from_tuples : Construct an IntervalIndex from an
            array-like of tuples.

        Notes
        -----
        Each element of `left` must be less than or equal to the `right`
        element at the same position. If an element is missing, it must be
        missing in both `left` and `right`. A TypeError is raised when
        using an unsupported type for `left` or `right`. At the moment,
        'category', 'object', and 'string' subtypes are not supported.

        Examples
        --------
        >>> pd.IntervalIndex.from_arrays([0, 1, 2], [1, 2, 3])
        IntervalIndex([(0, 1], (1, 2], (2, 3]],
                      dtype='interval[int64, right]')
        r-   )rr   r@   Nr   )r   rz   r-   rW   r{   )rX   leftr   rg   rt   rr   r@   r}   s           rP   rW   zIntervalIndex.from_arraysI  s    | == 	 	!-eV$e  E	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 u4000s   <A A c                    t          d| j                  5  t          j        ||||          }ddd           n# 1 swxY w Y   |                     ||          S )a  
        Construct an IntervalIndex from an array-like of tuples.

        Parameters
        ----------
        data : array-like (1-dimensional)
            Array of tuples.
        closed : {'left', 'right', 'both', 'neither'}, default 'right'
            Whether the intervals are closed on the left-side, right-side, both
            or neither.
        name : str, optional
            Name of the resulting IntervalIndex.
        copy : bool, default False
            By-default copy the data, this is compat only and ignored.
        dtype : dtype or None, default None
            If None, dtype will be inferred.

        Returns
        -------
        IntervalIndex

        See Also
        --------
        interval_range : Function to create a fixed frequency IntervalIndex.
        IntervalIndex.from_arrays : Construct an IntervalIndex from a left and
                                    right array.
        IntervalIndex.from_breaks : Construct an IntervalIndex from an array of
                                    splits.

        Examples
        --------
        >>> pd.IntervalIndex.from_tuples([(0, 1), (1, 2)])
        IntervalIndex([(0, 1], (1, 2]],
                       dtype='interval[int64, right]')
        r-   r   Nr   )r   rz   r-   from_tuplesr{   )rX   r|   rg   rt   rr   r@   arrs          rP   r   zIntervalIndex.from_tuples  s    X == 	Y 	Y+DdRWXXXC	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Ys...r   r   c                    |                      | j                  }t          |          }|                      | j                  }t          |          }t	          ||| j                  S )Nrg   )_maybe_convert_i8r   r   r   r   rg   )selfr   r   s      rP   _enginezIntervalIndex._engine  s_     %%di00,T22&&tz22-e44D%<<<<rR   keyr   c                    t          |           t          |t                    st          || j                  r| j        S dS 	 |                     |           dS # t          $ r Y dS w xY w)z
        return a boolean if this key is IN the index
        We *only* accept an Interval

        Parameters
        ----------
        key : Interval

        Returns
        -------
        bool
        FT)hashrG   r   r)   r@   hasnansget_locKeyError)r   r   s     rP   __contains__zIntervalIndex.__contains__  s     	S			#x(( 	$S$*55 $|#5	LL4 	 	 	55	s   A 
A)(A)slobjslicec                n    | j         |         }t          |                               || j                  S )zH
        Fastpath for __getitem__ when we know we have a slice.
        r   )rn   rF   r{   _name)r   r   ress      rP   _getitem_slicezIntervalIndex._getitem_slice  s1     jDzz%%c
%;;;rR   r6   c                J    t          j        | j        | j        gddg          S )Nr   r   )names)r6   rW   r   r   r   s    rP   _multiindexzIntervalIndex._multiindex  s&    %ty$*&=fgEVWWWWrR   c                j    | j         | j        | j        | j        d}t          t          |           |fd fS )N)r   r   rg   rt   )r   r   rg   rt   rZ   rF   )r   rY   s     rP   
__reduce__zIntervalIndex.__reduce__  s;    IZkI	
 
 "DJJ?D88rR   strc                    dS )z4Return a string of the type inferred from the valuesintervalrV   r   s    rP   inferred_typezIntervalIndex.inferred_type  s	     zrR   deepintc                p    | j                             |          | j                            |          z   S )a  
        Memory usage of the values.

        Parameters
        ----------
        deep : bool, default False
            Introspect the data deeply, interrogate
            `object` dtypes for system-level memory consumption.

        Returns
        -------
        bytes used
            Returns memory usage of the values in the Index in bytes.

        See Also
        --------
        numpy.ndarray.nbytes : Total bytes consumed by the elements of the
            array.

        Notes
        -----
        Memory usage does not include memory consumed by elements that
        are not components of the array if deep=False or if used on PyPy

        Examples
        --------
        >>> idx = pd.Index([1, 2, 3])
        >>> idx.memory_usage()
        24
        )r   )r   memory_usager   )r   r   s     rP   r   zIntervalIndex.memory_usage  s7    B y%%4%004:3J3JPT3J3U3UUUrR   c                "    | ddd         j         S )z
        Return True if the IntervalIndex is monotonic decreasing (only equal or
        decreasing values), else False
        N)is_monotonic_increasingr   s    rP   is_monotonic_decreasingz%IntervalIndex.is_monotonic_decreasing   s     DDbDz11rR   c                t   | j         }| j        }|                                                                 dk    rdS |j        s|j        rdS t                      }t          j        |                    d                    d         }|D ].}||         ||         f}||v r dS |	                    |           /dS )zX
        Return True if the IntervalIndex contains unique elements, else False.
        rB   FT)keepr   )
r   r   isnasum	is_uniquesetrI   where
duplicatedadd)r   r   r   
seen_pairs	check_idxidxpairs          rP   r   zIntervalIndex.is_unique(  s    
 y
99;;??q  5> 	U_ 	4UU
HT__%_8899!<	 	! 	!CIuSz*Dz!!uuNN4    trR   c                    | j         j        S )a  
        Return True if the IntervalIndex has overlapping intervals, else False.

        Two intervals overlap if they share a common point, including closed
        endpoints. Intervals that only have an open endpoint in common do not
        overlap.

        Returns
        -------
        bool
            Boolean indicating if the IntervalIndex has overlapping intervals.

        See Also
        --------
        Interval.overlaps : Check whether two Interval objects overlap.
        IntervalIndex.overlaps : Check an IntervalIndex elementwise for
            overlaps.

        Examples
        --------
        >>> index = pd.IntervalIndex.from_tuples([(0, 2), (1, 3), (4, 5)])
        >>> index
        IntervalIndex([(0, 2], (1, 3], (4, 5]],
              dtype='interval[int64, right]')
        >>> index.is_overlapping
        True

        Intervals that share closed endpoints overlap:

        >>> index = pd.interval_range(0, 3, closed="both")
        >>> index
        IntervalIndex([[0, 1], [1, 2], [2, 3]],
              dtype='interval[int64, both]')
        >>> index.is_overlapping
        True

        Intervals that only have an open endpoint in common do not overlap:

        >>> index = pd.interval_range(0, 3, closed="left")
        >>> index
        IntervalIndex([[0, 1), [1, 2), [2, 3)],
              dtype='interval[int64, left]')
        >>> index.is_overlapping
        False
        )r   is_overlappingr   s    rP   r   zIntervalIndex.is_overlapping@  s    ` |**rR   c                    t          |dd          }t          |t                    st          |t                    r|                     |j                  S t          t          t          t          f}t          ||          S )a	  
        Check if a given key needs i8 conversion. Conversion is necessary for
        Timestamp, Timedelta, DatetimeIndex, and TimedeltaIndex keys. An
        Interval-like requires conversion if its endpoints are one of the
        aforementioned types.

        Assumes that any list-like data has already been cast to an Index.

        Parameters
        ----------
        key : scalar or Index-like
            The key that should be checked for i8 conversion

        Returns
        -------
        bool
        r@   N)
rE   rG   r(   r   _needs_i8_conversionr   r   r   r2   r7   )r   r   	key_dtypei8_typess       rP   r   z"IntervalIndex._needs_i8_conversionr  sl    $ C$//	i// 	7:c83L3L 	7,,SX666y-H#x(((rR   c                   t          |          rt          |          }t          |          }|                     |          s|S t	          |          }t          |dd          }t          |t                    st          |t                    r\| 	                    |j
                  }| 	                    |j                  }|rt          nt          j        } |||| j                  S |rt          |          \  }}t          |t                     r|j        }nt          |t$                    r|j        }n{t          |t(          j        t(          j        f          r|                    d          }n?|j        t3          |j        d          }}|j        r|                    |j                   }| j        j        }||k    rt?          d| d|           |S )	a  
        Maybe convert a given key to its equivalent i8 value(s). Used as a
        preprocessing step prior to IntervalTree queries (self._engine), which
        expects numeric data.

        Parameters
        ----------
        key : scalar or list-like
            The key that should maybe be converted to i8.

        Returns
        -------
        scalar or list-like
            The original key if no conversion occurred, int if converted scalar,
            Index with an int64 dtype if converted list-like.
        r@   Nr   i8Frr   z)Cannot index an IntervalIndex of subtype z with values of dtype ) r!   r0   r   r   r$   rE   rG   r(   r   r   r   r   rk   rW   rg   r   r   ordinalr   _valuerI   
datetime64rJ   viewr@   r/   asi8r   r   _isnansubtype
ValueError)	r   r   scalarr   r   r   constructorkey_i8r   s	            rP   r   zIntervalIndex._maybe_convert_i8  s   "  	5s##C/44C((-- 	J3C$//	i// 	@:c83L3L 	@))#(33D**3955E&,K((-2KK;tU4;???? 	3 7 < <Iv#v&& +FI.. +FR]BN$CDD +T** !$	5+F+F+FvI{ 3  szk22
 *$i/G / /#,/ /  
 rR   r   sideLiteral['left', 'right']c                n   | j         st          d          t          |t          t          f          rt          d          |dk    r| j        j        s|dk    r*| j        j        s| j        }| j	        rt          |          }n| j        }| j        rt          |          }|                    ||          S )Nzrcan only get slices from an IntervalIndex if bounds are non-overlapping and all monotonic increasing or decreasingz,Interval objects are not currently supportedr   r   )rf   r   rG   r   rk   NotImplementedErrorr   r   r   rd   rQ   rc   rT   _searchsorted_monotonic)r   rO   r   sub_idxs       rP   r   z%IntervalIndex._searchsorted_monotonic  s    0 	M  
 em];<< 	V%&TUUU
 FNNty@NGOODI$EOjG /'..iG~ /'....ud;;;rR   int | slice | np.ndarrayc                   |                      |           t          |t                    rA| j        |j        k    rt	          |          | j        |j        k    | j        |j        k    z  }nt          || j                  r| 	                                }nq| j
        rt          nt          }| j        rt          nt          }	  || j        |           ||| j                  z  }n"# t          $ r}t	          |          |d}~ww xY w|                                }|dk    rt	          |          |dk    r!t!          |                                          S t%          j        |                    d                    }t          |t*                    r/|j        (t+          |j        t1          |           |j                  }|S )a6  
        Get integer location, slice or boolean mask for requested label.

        The `get_loc` method is used to retrieve the integer index, a slice for
        slicing objects, or a boolean mask indicating the presence of the label
        in the `IntervalIndex`.

        Parameters
        ----------
        key : label
            The value or range to find in the IntervalIndex.

        Returns
        -------
        int if unique index, slice if monotonic index, else mask
            The position or positions found. This could be a single
            number, a range, or an array of true/false values
            indicating the position(s) of the label.

        See Also
        --------
        IntervalIndex.get_indexer_non_unique : Compute indexer and
            mask for new index given the current index.
        Index.get_loc : Similar method in the base Index class.

        Examples
        --------
        >>> i1, i2 = pd.Interval(0, 1), pd.Interval(1, 2)
        >>> index = pd.IntervalIndex([i1, i2])
        >>> index.get_loc(1)
        0

        You can also supply a point inside an interval.

        >>> index.get_loc(1.5)
        1

        If a label is in several intervals, you get the locations of all the
        relevant intervals.

        >>> i3 = pd.Interval(0, 2)
        >>> overlapping_index = pd.IntervalIndex([i1, i2, i3])
        >>> overlapping_index.get_loc(0.5)
        array([ True, False,  True])

        Only exact matches will be returned if an interval is provided.

        >>> index.get_loc(pd.Interval(0, 1))
        0
        Nr   rB   u1)_check_indexing_errorrG   r   rg   r   r   r   r)   r@   r   ra   r   r   rb   rM   r   r   argmaxr
   maybe_booleans_to_slicer   r   stopstartlenstep)r   r   maskop_leftop_righterrmatchesr   s           rP   r   zIntervalIndex.get_loc  s   f 	""3'''c8$$ 	-{cj((smm#I)djCI.EFDD"3
33 
	-99;;DD !,4bb"G!.6rrBH-wty#..#tz1J1JJ - - -smm,- ((**a<<3--a<<+DKKMM:::)$))D//::c5!! 	8ch&6	3t99ch77C
s   #C% %
D/C??Dtargetr/   method
str | Nonelimit
int | None	tolerance
Any | Nonenpt.NDArray[np.intp]c                   t          |t                    rJ| j        j        r"| j        j        r|                     |          }n|                     |          d         }nxt          |j                  sIt          |j                  s5| 
                    |          }| j                            |j                  }n|                     |          d         S t          |          S )Nr   )rG   rk   r   r   r   _get_indexer_unique_sides_get_indexer_pointwiser#   r@   r%   r   r   get_indexervaluesr   )r   r   r   r   r   indexers         rP   _get_indexerzIntervalIndex._get_indexer8  s     fm,, 	:
 y" Atz'; A88@@55f==a@!&,// 	:?6<3P3P 	: ++F33Fl..v}==GG ..v66q99"7+++rR   1tuple[npt.NDArray[np.intp], npt.NDArray[np.intp]]c                   t          |          }|                     |          s-|                     |          s|                     |dd          S t	          |t
                    ra| j        j        r@| j        j        r4| 	                    |          }|dk    
                                d         }n|                     |          S t          |j                  s|                     |          s|                     |          S |                     |          }| j                            |j                  \  }}t%          |          t%          |          fS )aq  
        Compute indexer and mask for new index given the current index.

        The indexer should be then used as an input to ndarray.take to align the
        current data to the new index.

        Parameters
        ----------
        target : IntervalIndex or list of Intervals
            An iterable containing the values to be used for computing indexer.

        Returns
        -------
        indexer : np.ndarray[np.intp]
            Integers from 0 to n - 1 indicating that the index at these
            positions matches the corresponding target values. Missing values
            in the target are marked by -1.
        missing : np.ndarray[np.intp]
            An indexer into the target of the values not found.
            These correspond to the -1 in the indexer array.

        See Also
        --------
        Index.get_indexer : Computes indexer and mask for new index given
            the current index.
        Index.get_indexer_for : Returns an indexer even when non-unique.

        Examples
        --------
        >>> index = pd.Index(["c", "b", "a", "b", "b"])
        >>> index.get_indexer_non_unique(["b", "b"])
        (array([1, 3, 4, 1, 3, 4]), array([], dtype=int64))

        In the example below there are no matched values.

        >>> index = pd.Index(["c", "b", "a", "b", "b"])
        >>> index.get_indexer_non_unique(["q", "r", "t"])
        (array([-1, -1, -1]), array([0, 1, 2]))

        For this reason, the returned ``indexer`` contains only integers equal to -1.
        It demonstrates that there's no match between the index and the ``target``
        values at these positions. The mask [0, 1, 2] in the return value shows that
        the first, second, and third elements are missing.

        Notice that the return value is a tuple contains two items. In the example
        below the first item is an array of locations in ``index``. The second
        item is a mask shows that the first and third elements are missing.

        >>> index = pd.Index(["c", "b", "a", "b", "b"])
        >>> index.get_indexer_non_unique(["f", "b", "s"])
        (array([-1,  1,  3,  4, -1]), array([0, 2]))
        NFr*   r   r   )r0   _should_compare_should_partial_index_get_indexer_non_comparablerG   rk   r   r   r   r   nonzeror   r#   r@   r   r   get_indexer_non_uniquer   r   )r   r   r   missings       rP   r   z$IntervalIndex.get_indexer_non_uniqueU  sU   n f%%##F++ 	RD4N4Nv4V4V 	R 33FD3OOO.. 	Ry" ;tz'; ;88@@"b=1133A6226:::V\** 	R$2L2LV2T2T 	R..v666
 ++F33F#|BB6=QQGW"7++-@-I-IIIrR   c                    | j                             |j                   }| j                            |j                  }t          j        ||k    |d          }|S )zZ
        _get_indexer specialized to the case where both of our sides are unique.
        r   )r   r   r   rI   r   )r   r   left_indexerright_indexerr   s        rP   r   z'IntervalIndex._get_indexer_unique_sides  sO     y,,V[99
..v|<<(<=8,KKrR   c                   g g }}t          |          D ]#\  }}	 |                     |          }t          |t                    r(t	          j        |j        |j        |j        d          }nEt          j
        |          rt	          j        |d          }nt	          j        |          d         }no# t          $ r- |                    |           t	          j        dg          }Y n9t          $ r- |                    |           t	          j        dg          }Y nw xY w|                    |           %t	          j        |          }t#          |          t#          |          fS )zV
        pointwise implementation for get_indexer and get_indexer_non_unique.
        intpr@   rB   )ndminr   r   )	enumerater   rG   r   rI   aranger   r   r   r
   r   r}   r   r   appendr   concatenater   )r   r   r   r   ir   locss          rP   r   z$IntervalIndex._get_indexer_pointwise  sh    r'' 	! 	!FAs&||C((dE** -9TZDIVTTTDD^D)) -8D222DD 8D>>!,D & & &q!!!x~~$ & & & q!!!x~~	& NN4    .))"7++-@-I-IIIs   BB334D)3DDc                2    | j          o| j        j        dk     S )N   )r   r   	_na_countr   s    rP   _index_as_uniquezIntervalIndex._index_as_unique  s    &&E4<+AA+EErR   zKcannot handle overlapping indices; use IntervalIndex.get_indexer_non_uniquekindLiteral['loc', 'getitem']c                    |j         F|j         dk    s;d}|dk    rt          |          |dk    rt          |          st          |          t                                          ||          S )NrB   zClabel-based slicing with step!=1 is not supported for IntervalIndexlocgetitem)r   r   r.   super_convert_slice_indexer)r   r   r  msg	__class__s       rP   r  z$IntervalIndex._convert_slice_indexer  ss     CHMM XCu}} oo%y  055 *$S//)ww--c4888rR   c                (    | j         j        j        dv S )NrA   )r@   r   r  r   s    rP   _should_fallback_to_positionalz,IntervalIndex._should_fallback_to_positional  s     z!&$..rR   c                J    t          | |                              ||          S N)rE   _maybe_cast_slice_bound)r   rO   r   s      rP   r  z%IntervalIndex._maybe_cast_slice_bound  s"    tT""::5$GGGrR   r;   c                |    t          |t                    sdS t          | j        |g          }t	          |           S )NF)rG   r(   r   r@   r#   )r   r@   common_subtypes      rP   _is_comparable_dtypez"IntervalIndex._is_comparable_dtype  s>    %// 	5)4:u*=>>">2222rR   c                8    t          | j        j        d          S )aM  
        Return left bounds of the intervals in the IntervalIndex.

        The left bounds of each interval in the IntervalIndex are
        returned as an Index. The datatype of the left bounds is the
        same as the datatype of the endpoints of the intervals.

        Returns
        -------
        Index
            An Index containing the left bounds of the intervals.

        See Also
        --------
        IntervalIndex.right : Return the right bounds of the intervals
            in the IntervalIndex.
        IntervalIndex.mid : Return the mid-point of the intervals in
            the IntervalIndex.
        IntervalIndex.length : Return the length of the intervals in
            the IntervalIndex.

        Examples
        --------
        >>> iv_idx = pd.IntervalIndex.from_arrays([1, 2, 3], [4, 5, 6], closed="right")
        >>> iv_idx.left
        Index([1, 2, 3], dtype='int64')

        >>> iv_idx = pd.IntervalIndex.from_tuples(
        ...     [(1, 4), (2, 5), (3, 6)], closed="left"
        ... )
        >>> iv_idx.left
        Index([1, 2, 3], dtype='int64')
        Fr   )r/   rn   r   r   s    rP   r   zIntervalIndex.left  s    F TZ_51111rR   c                8    t          | j        j        d          S )aQ  
        Return right bounds of the intervals in the IntervalIndex.

        The right bounds of each interval in the IntervalIndex are
        returned as an Index. The datatype of the right bounds is the
        same as the datatype of the endpoints of the intervals.

        Returns
        -------
        Index
            An Index containing the right bounds of the intervals.

        See Also
        --------
        IntervalIndex.left : Return the left bounds of the intervals
            in the IntervalIndex.
        IntervalIndex.mid : Return the mid-point of the intervals in
            the IntervalIndex.
        IntervalIndex.length : Return the length of the intervals in
            the IntervalIndex.

        Examples
        --------
        >>> iv_idx = pd.IntervalIndex.from_arrays([1, 2, 3], [4, 5, 6], closed="right")
        >>> iv_idx.right
        Index([4, 5, 6], dtype='int64')

        >>> iv_idx = pd.IntervalIndex.from_tuples(
        ...     [(1, 4), (2, 5), (3, 6)], closed="left"
        ... )
        >>> iv_idx.right
        Index([4, 5, 6], dtype='int64')
        Fr   )r/   rn   r   r   s    rP   r   zIntervalIndex.right!  s    F TZ%E2222rR   c                8    t          | j        j        d          S )ae  
        Return the midpoint of each interval in the IntervalIndex as an Index.

        Each midpoint is calculated as the average of the left and right bounds
        of each interval. The midpoints are returned as a pandas Index object.

        Returns
        -------
        pandas.Index
            An Index containing the midpoints of each interval.

        See Also
        --------
        IntervalIndex.left : Return the left bounds of the intervals
            in the IntervalIndex.
        IntervalIndex.right : Return the right bounds of the intervals
            in the IntervalIndex.
        IntervalIndex.length : Return the length of the intervals in
            the IntervalIndex.

        Notes
        -----
        The midpoint is the average of the interval bounds, potentially resulting
        in a floating-point number even if bounds are integers. The returned Index
        will have a dtype that accurately holds the midpoints. This computation is
        the same regardless of whether intervals are open or closed.

        Examples
        --------
        >>> iv_idx = pd.IntervalIndex.from_arrays([1, 2, 3], [4, 5, 6])
        >>> iv_idx.mid
        Index([2.5, 3.5, 4.5], dtype='float64')

        >>> iv_idx = pd.IntervalIndex.from_tuples([(1, 4), (2, 5), (3, 6)])
        >>> iv_idx.mid
        Index([2.5, 3.5, 4.5], dtype='float64')
        Fr   )r/   rn   midr   s    rP   r!  zIntervalIndex.midF  s    N TZ^%0000rR   c                8    t          | j        j        d          S )a`  
        Calculate the length of each interval in the IntervalIndex.

        This method returns a new Index containing the lengths of each interval
        in the IntervalIndex. The length of an interval is defined as the difference
        between its end and its start.

        Returns
        -------
        Index
            An Index containing the lengths of each interval.

        See Also
        --------
        Interval.length : Return the length of the Interval.

        Examples
        --------
        >>> intervals = pd.IntervalIndex.from_arrays(
        ...     [1, 2, 3], [4, 5, 6], closed="right"
        ... )
        >>> intervals.length
        Index([3, 3, 3], dtype='int64')

        >>> intervals = pd.IntervalIndex.from_tuples([(1, 5), (6, 10), (11, 15)])
        >>> intervals.length
        Index([4, 4, 4], dtype='int64')
        Fr   )r/   rn   lengthr   s    rP   r#  zIntervalIndex.lengtho  s    < TZ&U3333rR   sortc                h   | j         j        r"| j        j        r|                     |          }nm|j         j        rL|j        j        r@|                                                                 dk    r|                    |           }n|                     |          }|r|                                }|S )zL
        intersection specialized to the case with matching dtypes.
        rB   )r   r   r   _intersection_uniquer   r   _intersection_non_uniquesort_values)r   otherr$  takens       rP   _intersectionzIntervalIndex._intersection  s    
 9 	94:#7 	9--e44EEZ! 	9ek&; 	9		@Q@QUV@V@V ..t44EE 11%88E 	(%%''ErR   r)  c                :   | j                             |j                   }| j                            |j                  }||k    |dk    z  }|                    |                                d                   }t          |          }|                     |          S )a'  
        Used when the IntervalIndex does not have any common endpoint,
        no matter left or right.
        Return the intersection with another IntervalIndex.
        Parameters
        ----------
        other : IntervalIndex
        Returns
        -------
        IntervalIndex
        r   r   )r   r   r   taker   r+   )r   r)  lindexerrindexermatchr   s         rP   r&  z"IntervalIndex._intersection_unique  s     9((44:))%+66X%(b.9-- 233//yy!!!rR   c                   t          j        t          |           t                    }| j        rK|j        rDt          j        t          |                     |                                          d         }d||<   t          t          |j	        |j
        d                    }t          t          | j	        | j
        d                    D ]\  }}||v rd||<   | |         S )a  
        Used when the IntervalIndex does have some common endpoints,
        on either sides.
        Return the intersection with another IntervalIndex.

        Parameters
        ----------
        other : IntervalIndex

        Returns
        -------
        IntervalIndex
        r  r   T)strict)rI   zerosr   rm   r   r  r   r   zipr   r   r  )r   r)  r   first_nan_loc
other_tupsr  tups          rP   r'  z&IntervalIndex._intersection_non_unique  s      xD		...< 	'EM 	'Ic$ii00=a@M"&DUZTBBBCC
DItz$ G G GHH 	 	FAsj  QDzrR   
np.ndarrayc                     t          d          )NzRIntervalIndex does not use libjoin fastpaths or pass values to IndexEngine objectsr   r   s    rP   _get_engine_targetz IntervalIndex._get_engine_target  s     ""
 
 	
rR   c                     t          d          )Nz,IntervalIndex does not use libjoin fastpathsr:  )r   results     rP   _from_join_targetzIntervalIndex._from_join_target  s    !"PQQQrR   )NNNNT)rg   rp   r@   rq   rr   rs   rt   ru   rv   rm   rw   r	   )r   NFN)
rg   rp   rt   ru   rr   rm   r@   rq   rw   rk   )
rg   r<   rt   ru   rr   rm   r@   rq   rw   rk   )rw   r   )r   r   rw   rm   )r   r   rw   rk   )rw   r6   )rw   r   )F)r   rm   rw   r   rw   rm   )r   )r   r   )rw   r   )NNN)
r   r/   r   r   r   r   r   r   rw   r   )r   r/   rw   r   )r   rk   rw   r   )r   r   r  r  )r   r   )r@   r;   rw   rm   )rw   r/   )r$  rm   )r)  rk   rw   rk   )rw   r8  )2rz   
__module____qualname____doc___typ__annotations___can_hold_stringsr-   	_data_clsr~   classmethodr   rW   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r  _requires_unique_msgr  r  r  r  r   r   r!  r#  r+  r&  r'  r;  r>  __classcell__)r  s   @rP   rk   rk      s        "L L\ D &&&&OOOI -1"  $!%, , , , ,2  -4 $"-1 -1 -1 -1 [-1^ 
 &- $"A1 A1 A1 A1 [A1F  &- $"-/ -/ -/ -/ [-/d = = = ^=   2< < < < X X X ^X9 9 9    X!V !V !V !V !VJ 2 2 2 ^2    ^. /+ /+ /+ X/+b) ) ) )2= = =~< < < < <:O O O Oh "  $, , , , ,:PJ PJ PJ PJd
 
 
 
J J J J@ F F F ^F 	V 9 9 9 9 9 9 / / / ^/H H H H3 3 3 3 "2 "2 "2 ^"2H "3 "3 "3 ^"3H &1 &1 &1 ^&1P 4 4 4 X4D    (" " " ",   >
 
 
 
R R R R R R RrR   rk   rw   rm   c                    t          t          |           t          | t                    t          | t                    | du g          S )zJ
    Helper for interval_range to check if start/end are valid types.
    N)anyr"   rG   r   r   )endpoints    rP   _is_valid_endpointrN    sH     hx++x++		
  rR   c                    d }d }t          |           rt          |          p@ ||           o
 ||          p* ||           o
 ||          pt          j        | |          S )zK
    Helper for interval_range to check type compat of start/end/freq.
    c                :    t          | t          t          f          S r  )rG   r   r   xs    rP   <lambda>z%_is_type_compatible.<locals>.<lambda>      ZIz+BCC rR   c                :    t          | t          t          f          S r  )rG   r   r   rQ  s    rP   rS  z%_is_type_compatible.<locals>.<lambda>  rT  rR   )r"   comany_none)abis_ts_compatis_td_compats       rP   _is_type_compatibler\    s~     DCLCCL	1	&)A,, 	LOO/Q	LOO/Q	 <1	rR   r   rt   ru   r<   c           	     >   t          |           } t          |          }| | n|}|)t          j        || |          rt          |          rdnd}t          j        | |||          dk    rt          d          t          |           st          d|            t          |          st          d|           t          |          }|Et          |          s6	 t          |          }n%# t
          $ r}t          d|           |d}~ww xY wt          t          | |          t          | |          t          ||          g          st          d	          ||dz  }t          |          rt          j        d
          }t          j        | ||          rt          | t          j        t          j        f          r>t          |t          j        t          j        f          r| j        |j        k    r| j        }nwt          | t$          t          j        f          sBt          |t$          t          j        f          s!t          |t$          t          j        f          rt          j        d          }t          j        | ||dz  z   |          }	t)          |	|          }	nL|t+          || z
  |z            dz   }n| ||dz
  |z  z
  } n|| |dz
  |z  z   }t          j        | ||          }	t          d t          j        | ||          D                       rt)          |	|          }	n<t          |t0                    rt3          | |||          }	nt5          | |||          }	t6                              |	||t;          |	j        |                    S )a  
    Return a fixed frequency IntervalIndex.

    Parameters
    ----------
    start : numeric or datetime-like, default None
        Left bound for generating intervals.
    end : numeric or datetime-like, default None
        Right bound for generating intervals.
    periods : int, default None
        Number of periods to generate.
    freq : numeric, str, Timedelta, datetime.timedelta, or DateOffset, default None
        The length of each interval. Must be consistent with the type of start
        and end, e.g. 2 for numeric, or '5H' for datetime-like.  Default is 1
        for numeric and 'D' for datetime-like.
    name : str, default None
        Name of the resulting IntervalIndex.
    closed : {'left', 'right', 'both', 'neither'}, default 'right'
        Whether the intervals are closed on the left-side, right-side, both
        or neither.

    Returns
    -------
    IntervalIndex
        Object with a fixed frequency.

    See Also
    --------
    IntervalIndex : An Index of intervals that are all closed on the same side.

    Notes
    -----
    Of the four parameters ``start``, ``end``, ``periods``, and ``freq``,
    exactly three must be specified. If ``freq`` is omitted, the resulting
    ``IntervalIndex`` will have ``periods`` linearly spaced elements between
    ``start`` and ``end``, inclusively.

    To learn more about datetime-like frequency strings, please see
    :ref:`this link<timeseries.offset_aliases>`.

    Examples
    --------
    Numeric ``start`` and  ``end`` is supported.

    >>> pd.interval_range(start=0, end=5)
    IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]],
                  dtype='interval[int64, right]')

    Additionally, datetime-like input is also supported.

    >>> pd.interval_range(
    ...     start=pd.Timestamp("2017-01-01"), end=pd.Timestamp("2017-01-04")
    ... )
    IntervalIndex([(2017-01-01 00:00:00, 2017-01-02 00:00:00],
                   (2017-01-02 00:00:00, 2017-01-03 00:00:00],
                   (2017-01-03 00:00:00, 2017-01-04 00:00:00]],
                  dtype='interval[datetime64[us], right]')

    The ``freq`` parameter specifies the frequency between the left and right.
    endpoints of the individual intervals within the ``IntervalIndex``.  For
    numeric ``start`` and ``end``, the frequency must also be numeric.

    >>> pd.interval_range(start=0, periods=4, freq=1.5)
    IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]],
                  dtype='interval[float64, right]')

    Similarly, for datetime-like ``start`` and ``end``, the frequency must be
    convertible to a DateOffset.

    >>> pd.interval_range(start=pd.Timestamp("2017-01-01"), periods=3, freq="MS")
    IntervalIndex([(2017-01-01 00:00:00, 2017-02-01 00:00:00],
                   (2017-02-01 00:00:00, 2017-03-01 00:00:00],
                   (2017-03-01 00:00:00, 2017-04-01 00:00:00]],
                  dtype='interval[datetime64[us], right]')

    Specify ``start``, ``end``, and ``periods``; the frequency is generated
    automatically (linearly spaced).

    >>> pd.interval_range(start=0, end=6, periods=4)
    IntervalIndex([(0.0, 1.5], (1.5, 3.0], (3.0, 4.5], (4.5, 6.0]],
              dtype='interval[float64, right]')

    The ``closed`` parameter specifies which endpoints of the individual
    intervals within the ``IntervalIndex`` are closed.

    >>> pd.interval_range(end=5, periods=4, closed="both")
    IntervalIndex([[1, 2], [2, 3], [3, 4], [4, 5]],
                  dtype='interval[int64, both]')
    NrB   D   zVOf the four parameters: start, end, periods, and freq, exactly three must be specifiedz,start must be numeric or datetime-like, got z*end must be numeric or datetime-like, got z7freq must be numeric or convertible to DateOffset, got z+start, end, freq need to be type compatibleint64float64g?c              3  4   K   | ]}t          |          V  d S r  )r   ).0rR  s     rP   	<genexpr>z!interval_range.<locals>.<genexpr>  s(      EEz!}}EEEEEErR   )r   endperiodsfreq)r   rg   )rt   rg   r@   )r   rV  rW  r"   count_not_noner   rN  r,   r   allr\  rM   rI   r@   all_not_nonerG   integerfloatingfloatr  r   r   linspacenot_noner   r3   r8   rk   r   r(   )
r   re  rf  rg  rt   rg   rM  r   r@   r   s
             rP   interval_rangerp    s   D #5))E
 
%
%C)uusH|WeS99|h''0qqS
%gt44994
 
 	

 e$$ QOOOPPPc"" MKcKKLLLw''G	$	T??DD 	 	 	P$PP 	 s++t,,T**	
  G EFFF 1  #S(7++E3-- 	652:r{";<<,sRZ$=>>, K39,,55"+"677,cE2;#788, dUBK$899,
 ++YucTCZ&8$??F+FE::FF sU{t344q8w{d22w{d22[W55FEEcl5#t&D&DEEEEE 	;+FE::F	Hi	(	( S%S'MMM u#wTRRR$$FL@@@	 %   s   C- -
D7D

Dr?  )NNNNNr   )rt   ru   rg   r<   rw   rk   )`rB  
__future__r   operatorr   r   typingr   r   r   r	   numpyrI   pandas._libsr
   pandas._libs.intervalr   r   r   pandas._libs.tslibsr   r   r   r   r   pandas.errorsr   pandas.util._decoratorsr   r   pandas.util._exceptionsr   pandas.core.dtypes.castr   r   r   r   r   r   pandas.core.dtypes.commonr   r   r   r    r!   r"   r#   r$   r%   r&   pandas.core.dtypes.dtypesr'   r(   pandas.core.dtypes.missingr)   pandas.core.algorithmsr+   pandas.core.arrays.datetimeliker,   pandas.core.arrays.intervalr-   pandas.core.commoncorecommonrV  pandas.core.indexersr.   pandas.core.indexes.baser/   r0   r1   pandas.core.indexes.datetimesr2   r3   pandas.core.indexes.extensionr4   r5   pandas.core.indexes.multir6   pandas.core.indexes.timedeltasr7   r8   collections.abcr9   pandas._typingr:   r;   r<   r=   rQ   rT   rZ   rk   rN  r\  rp  rV   rR   rP   <module>r     si     " " " " " "                                     
              , + + + + +        6 5 5 5 5 5                                              = < < < < < ) ) ) ) ) ) < < < < < <      !                 : : : : : :         
               1 0 0 0 0 0       
  ((((((           Q Q Q"Q Q Q"      k*MEEE	 	 	   .9=PTUUUHFR FR FR FR FRN FR FR  VU  FE FRV"       H
	 !(w w w w w w wrR   