
    Eg                       d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
 ddlZddlZddlmZmZmZmZ ddlmZmZmZmZmZmZ ddlmZ dd	lmZ dd
lm Z 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,m-Z-m.Z.m/Z/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z? ddl@mAZAmBZB ddlCmDZD ddlEmFZGmHZHmIZI ddlJmKZK erddlmLZLmMZMmNZN ddlOmPZPmQZQmRZR ddlSmTZTmUZU dzdZVd{dZWd|d"ZXejY        ejZ        ej[        ej\        ej]        ej^        ej_        ej`        eja        ejb        ejc        ejd        eje        ejf        d#Zgd}d$Zhd~d%Zid& Zjdd(Zkddd+ZlejZmd,Zndd0Zo	 	 	 	 ddd9Zp e ed:           ed;           ed<          =          	 	 	 dddA            Zq	 	 	 	 	 dddFZr	 	 	 	 	 dddGZs	 dddIZt	 	 dddMZu	 dddNZv	 	 	 	 	 dddVZw	 	 	 dddZZx	 	 ddddZyh deZzdddgZ{	 	 	 	 dddnZ|ddoZ}ddpZ~ddtZ	 	 dddyZdS )zl
Generic data algorithms. This module is experimental at the moment and not
intended for public consumption
    )annotationsN)dedent)TYPE_CHECKINGLiteralcast)algos	hashtableiNaTlib)AnyArrayLike	ArrayLikeAxisIntDtypeObjTakeIndexernpt)doc)find_stack_level)'construct_1d_object_array_from_listlikenp_find_common_type)ensure_float64ensure_objectensure_platform_intis_array_likeis_bool_dtypeis_complex_dtypeis_dict_likeis_extension_array_dtypeis_float_dtype
is_integeris_integer_dtypeis_list_likeis_object_dtypeis_signed_integer_dtypeneeds_i8_conversion)concat_compat)BaseMaskedDtypeCategoricalDtypeExtensionDtypeNumpyEADtype)ABCDatetimeArrayABCExtensionArrayABCIndexABCMultiIndex	ABCSeriesABCTimedeltaArray)isnana_value_for_dtype)take_nd)arrayensure_wrapped_if_datetimelikeextract_array)validate_indices)ListLikeNumpySorterNumpyValueArrayLike)CategoricalIndexSeries)BaseMaskedArrayExtensionArrayvaluesr   return
np.ndarrayc                   t          | t                    st          | d          } t          | j                  r!t          t          j        |                     S t          | j        t                    r?t          d|           } | j
        st          | j                  S t          j        |           S t          | j        t                    rt          d|           } | j        S t          | j                  rjt          | t          j                  r't          j        |                               d          S t          j        |                               dd          S t'          | j                  rt          j        |           S t)          | j                  r1| j        j        dv rt-          |           S t          j        |           S t/          | j                  rt          t          j        |           S t1          | j                  r1|                     d	          }t          t          j        |          }|S t          j        | t2          
          } t          |           S )a  
    routine to ensure that our data is of the correct
    input dtype for lower-level routines

    This will coerce:
    - ints -> int64
    - uint -> uint64
    - bool -> uint8
    - datetimelike -> i8
    - datetime64tz -> i8 (in local tz)
    - categorical -> codes

    Parameters
    ----------
    values : np.ndarray or ExtensionArray

    Returns
    -------
    np.ndarray
    Textract_numpyr=   r:   uint8Fcopy)         i8dtype)
isinstancer-   r5   r"   rM   r   npasarrayr&   r   _hasna_ensure_data_datar'   codesr   ndarrayviewastyper    r   itemsizer   r   r$   object)r?   npvaluess     K/var/www/sysmax/venv/lib/python3.11/site-packages/pandas/core/algorithms.pyrR   rR   j   s!   , fm,, ;vT:::v|$$ -RZ//000	FL/	2	2 *'00} 	.  ---z&!!!	FL"2	3	3 ! mV,,|	v|	$	$ fbj)) 	B:f%%**7333 :f%%,,W5,AAA	&,	'	' z&!!!		%	%  < K//!&)))z&!!!	&,	'	' BJ''' 
V\	*	* ;;t$$
H-- Zf---F       rM   r   originalr   c                   t          | t                    r| j        |k    r| S t          |t          j                  s,|                                }|                    | |          } n|                     |d          } | S )z
    reverse of _ensure_data

    Parameters
    ----------
    values : np.ndarray or ExtensionArray
    dtype : np.dtype or ExtensionDtype
    original : AnyArrayLike

    Returns
    -------
    ExtensionArray or np.ndarray
    rL   FrF   )rN   r+   rM   rO   construct_array_type_from_sequencerW   )r?   rM   r]   clss       r[   _reconstruct_datarb      s      &+,, 1F1FeRX&& 2 ((**##F%#88 u511Mr\   	func_namestrc                   t          | t          t          t          t          j        f          s|dk    r+t          j        | dt          t                                 t          j        | d          }|dv r4t          | t                    rt          |           } t          |           } nt	          j        |           } | S )z5
    ensure that we are arraylike if not already
    isin-targetsz with argument that is not not a Series, Index, ExtensionArray, or np.ndarray is deprecated and will raise in a future version.
stacklevelFskipna)mixedstringmixed-integer)rN   r,   r.   r+   rO   rU   warningswarnFutureWarningr   r   infer_dtypetuplelistr   rP   )r?   rc   inferreds      r[   _ensure_arraylikeru      s     fx4ErzRSS (&&M " " " +--    ?6%888;;;&%(( &f<VDDFFZ''FMr\   )
complex128	complex64float64float32uint64uint32uint16rE   int64int32int16int8rl   rY   c                `    t          |           } t          |           }t          |         }|| fS )z
    Parameters
    ----------
    values : np.ndarray

    Returns
    -------
    htable : HashTable subclass
    values : ndarray
    )rR   _check_object_for_strings_hashtables)r?   ndtyper	   s      r[   _get_hashtable_algor     s3     &!!F&v..FF#Ifr\   c                Z    | j         j        }|dk    rt          j        | d          rd}|S )z
    Check if we can use string hashtable instead of object hashtable.

    Parameters
    ----------
    values : ndarray

    Returns
    -------
    str
    rY   Fri   rl   )rM   namer   is_string_array)r?   r   s     r[   r   r     s=     \F ve444 	FMr\   c                     t          |           S )a3
  
    Return unique values based on a hash table.

    Uniques are returned in order of appearance. This does NOT sort.

    Significantly faster than numpy.unique for long enough sequences.
    Includes NA values.

    Parameters
    ----------
    values : 1d array-like

    Returns
    -------
    numpy.ndarray or ExtensionArray

        The return can be:

        * Index : when the input is an Index
        * Categorical : when the input is a Categorical dtype
        * ndarray : when the input is a Series/ndarray

        Return numpy.ndarray or ExtensionArray.

    See Also
    --------
    Index.unique : Return unique values from an Index.
    Series.unique : Return unique values of Series object.

    Examples
    --------
    >>> pd.unique(pd.Series([2, 1, 3, 3]))
    array([2, 1, 3])

    >>> pd.unique(pd.Series([2] + [1] * 5))
    array([2, 1])

    >>> pd.unique(pd.Series([pd.Timestamp("20160101"), pd.Timestamp("20160101")]))
    array(['2016-01-01T00:00:00.000000000'], dtype='datetime64[ns]')

    >>> pd.unique(
    ...     pd.Series(
    ...         [
    ...             pd.Timestamp("20160101", tz="US/Eastern"),
    ...             pd.Timestamp("20160101", tz="US/Eastern"),
    ...         ]
    ...     )
    ... )
    <DatetimeArray>
    ['2016-01-01 00:00:00-05:00']
    Length: 1, dtype: datetime64[ns, US/Eastern]

    >>> pd.unique(
    ...     pd.Index(
    ...         [
    ...             pd.Timestamp("20160101", tz="US/Eastern"),
    ...             pd.Timestamp("20160101", tz="US/Eastern"),
    ...         ]
    ...     )
    ... )
    DatetimeIndex(['2016-01-01 00:00:00-05:00'],
            dtype='datetime64[ns, US/Eastern]',
            freq=None)

    >>> pd.unique(np.array(list("baabc"), dtype="O"))
    array(['b', 'a', 'c'], dtype=object)

    An unordered Categorical will return categories in the
    order of appearance.

    >>> pd.unique(pd.Series(pd.Categorical(list("baabc"))))
    ['b', 'a', 'c']
    Categories (3, object): ['a', 'b', 'c']

    >>> pd.unique(pd.Series(pd.Categorical(list("baabc"), categories=list("abc"))))
    ['b', 'a', 'c']
    Categories (3, object): ['a', 'b', 'c']

    An ordered Categorical preserves the category ordering.

    >>> pd.unique(
    ...     pd.Series(
    ...         pd.Categorical(list("baabc"), categories=list("abc"), ordered=True)
    ...     )
    ... )
    ['b', 'a', 'c']
    Categories (3, object): ['a' < 'b' < 'c']

    An array of tuples

    >>> pd.unique(pd.Series([("a", "b"), ("b", "a"), ("a", "c"), ("b", "a")]).values)
    array([('a', 'b'), ('b', 'a'), ('a', 'c')], dtype=object)
    )unique_with_mask)r?   s    r[   uniquer   3  s    | F###r\   intc                    t          |           dk    rdS t          |           } t          j        |                                                     d                    dk                                    }|S )aH  
    Return the number of unique values for integer array-likes.

    Significantly faster than pandas.unique for long enough sequences.
    No checks are done to ensure input is integral.

    Parameters
    ----------
    values : 1d array-like

    Returns
    -------
    int : The number of unique values in ``values``
    r   intp)lenrR   rO   bincountravelrW   sum)r?   results     r[   nunique_intsr     sb     6{{aq&!!Fk&,,..//7788A=BBDDFMr\   masknpt.NDArray[np.bool_] | Nonec                   t          | d          } t          | j        t                    r|                                 S | }t          |           \  }}  |t          |                     }|-|                    |           }t          ||j        |          }|S |                    | |          \  }}t          ||j        |          }|J ||                    d          fS )z?See algorithms.unique for docs. Takes a mask for masked arrays.r   rc   Nr   bool)	ru   rN   rM   r(   r   r   r   rb   rW   )r?   r   r]   r	   tableuniquess         r[   r   r     s    v:::F&,// }}H+F33IvIc&kk""E|,,v&&#GX^XFF V$77#GX^XFFF++++r\   i@B compsr7   npt.NDArray[np.bool_]c                   t          |           s%t          dt          |           j         d          t          |          s%t          dt          |          j         d          t	          |t
          t          t          t          j	        f          s`t          |          }t          |d          }t          |          dk    r,|j        j        dv rt          |           st!          |          }n<t	          |t"                    rt          j        |          }nt'          |dd          }t          | d	          }t'          |d
          }t	          |t          j	                  s|                    |          S t+          |j                  r"t-          |                              |          S t+          |j                  r4t/          |j                  s t          j        |j        t4                    S t+          |j                  r(t)          ||                    t8                              S t	          |j        t:                    r4t)          t          j        |          t          j        |                    S t          |          t>          k    rLt          |          dk    r9|j        t8          k    r)tA          |          !                                rd }nXd }nTtE          |j        |j                  }|                    |d          }|                    |d          }tF          j$        } |||          S )z
    Compute the isin boolean array.

    Parameters
    ----------
    comps : list-like
    values : list-like

    Returns
    -------
    ndarray[bool]
        Same length as `comps`.
    zIonly list-like objects are allowed to be passed to isin(), you passed a ``rf   r   r   iufcbT)rD   extract_rangeisinrC   rL      c                    t          j        t          j        | |                                          t          j        |                     S N)rO   
logical_orr   r   isnan)cvs     r[   fzisin.<locals>.f  s2    }RWQ]]%8%8%:%:BHQKKHHHr\   c                P    t          j        | |                                          S r   )rO   r   r   )abs     r[   <lambda>zisin.<locals>.<lambda>  s    RWQ]]0022 r\   FrF   )%r!   	TypeErrortype__name__rN   r,   r.   r+   rO   rU   rs   ru   r   rM   kindr#   r   r-   r3   r5   r   r$   pd_arrayr"   zerosshaper   rW   rY   r(   rP   _MINIMUM_COMP_ARR_LENr0   anyr   htableismember)r   r?   orig_valuescomps_arrayr   commons         r[   r   r     s=     
@(,U(<@ @ @
 
 	
  
A(,V(=A A A
 
 	

 fx4ErzRSS O6ll";.III KK!OO!W,,+E22 -
 =[IIF	FM	*	* O&!!vTNNN#EV<<<K4@@@Kk2:.. A'''	[.	/	/ A$$))&111	V\	*	* A?;CT3U3U Ax)6666	V\	*	* AKv!6!6777	FL.	1	1 ABJ{++RZ-?-?@@@ 	K000KK2'' << 	3I I I I 32AA %V\;3DEEvE22!((e(<<O1[&!!!r\   Tuse_na_sentinelr   	size_hint
int | Nonena_valuerY   'tuple[npt.NDArray[np.intp], np.ndarray]c                   | }| j         j        dv rt          }t          |           \  }}  ||pt	          |                     }|                    | d|||          \  }}	t          ||j         |          }t          |	          }	|	|fS )a(  
    Factorize a numpy array to codes and uniques.

    This doesn't do any coercion of types or unboxing before factorization.

    Parameters
    ----------
    values : ndarray
    use_na_sentinel : bool, default True
        If True, the sentinel -1 will be used for NaN values. If False,
        NaN values will be encoded as non-negative integers and will not drop the
        NaN from the uniques of the values.
    size_hint : int, optional
        Passed through to the hashtable's 'get_labels' method
    na_value : object, optional
        A value in `values` to consider missing. Note: only use this
        parameter when you know that you don't have any values pandas would
        consider missing in the array (NaN for float data, iNaT for
        datetimes, etc.).
    mask : ndarray[bool], optional
        If not None, the mask is used as indicator for missing values
        (True = missing, False = valid) instead of `na_value` or
        condition "val != val".

    Returns
    -------
    codes : ndarray[np.intp]
    uniques : ndarray
    mM)na_sentinelr   r   	ignore_na)rM   r   r
   r   r   	factorizerb   r   )
r?   r   r   r   r   r]   
hash_klassr   r   rT   s
             r[   factorize_arrayr   $  s    H H|D  
 ,V44JJy/CKK00E__! %  NGU  BBG&&E'>r\   z    values : sequence
        A 1-D sequence. Sequences that aren't pandas objects are
        coerced to ndarrays before factorization.
    zt    sort : bool, default False
        Sort `uniques` and shuffle `codes` to maintain the
        relationship.
    zG    size_hint : int, optional
        Hint to the hashtable sizer.
    )r?   sortr   Fr   %tuple[np.ndarray, np.ndarray | Index]c                   t          | t          t          f          r|                     ||          S t	          | d          } | }t          | t
          t          f          r$| j        |                     |          \  }}||fS t          | t          j	                  s|                     |          \  }}nt          j
        |           } |s_| j        t          k    rOt          |           }|                                r,t          | j        d          }t          j        |||           } t#          | ||	          \  }}|r*t%          |          d
k    rt'          |||dd          \  }}t)          ||j        |          }||fS )aN  
    Encode the object as an enumerated type or categorical variable.

    This method is useful for obtaining a numeric representation of an
    array when all that matters is identifying distinct values. `factorize`
    is available as both a top-level function :func:`pandas.factorize`,
    and as a method :meth:`Series.factorize` and :meth:`Index.factorize`.

    Parameters
    ----------
    {values}{sort}
    use_na_sentinel : bool, default True
        If True, the sentinel -1 will be used for NaN values. If False,
        NaN values will be encoded as non-negative integers and will not drop the
        NaN from the uniques of the values.

        .. versionadded:: 1.5.0
    {size_hint}
    Returns
    -------
    codes : ndarray
        An integer ndarray that's an indexer into `uniques`.
        ``uniques.take(codes)`` will have the same values as `values`.
    uniques : ndarray, Index, or Categorical
        The unique valid values. When `values` is Categorical, `uniques`
        is a Categorical. When `values` is some other pandas object, an
        `Index` is returned. Otherwise, a 1-D ndarray is returned.

        .. note::

           Even if there's a missing value in `values`, `uniques` will
           *not* contain an entry for it.

    See Also
    --------
    cut : Discretize continuous-valued array.
    unique : Find the unique value in an array.

    Notes
    -----
    Reference :ref:`the user guide <reshaping.factorize>` for more examples.

    Examples
    --------
    These examples all show factorize as a top-level method like
    ``pd.factorize(values)``. The results are identical for methods like
    :meth:`Series.factorize`.

    >>> codes, uniques = pd.factorize(np.array(['b', 'b', 'a', 'c', 'b'], dtype="O"))
    >>> codes
    array([0, 0, 1, 2, 0])
    >>> uniques
    array(['b', 'a', 'c'], dtype=object)

    With ``sort=True``, the `uniques` will be sorted, and `codes` will be
    shuffled so that the relationship is the maintained.

    >>> codes, uniques = pd.factorize(np.array(['b', 'b', 'a', 'c', 'b'], dtype="O"),
    ...                               sort=True)
    >>> codes
    array([1, 1, 0, 2, 1])
    >>> uniques
    array(['a', 'b', 'c'], dtype=object)

    When ``use_na_sentinel=True`` (the default), missing values are indicated in
    the `codes` with the sentinel value ``-1`` and missing values are not
    included in `uniques`.

    >>> codes, uniques = pd.factorize(np.array(['b', None, 'a', 'c', 'b'], dtype="O"))
    >>> codes
    array([ 0, -1,  1,  2,  0])
    >>> uniques
    array(['b', 'a', 'c'], dtype=object)

    Thus far, we've only factorized lists (which are internally coerced to
    NumPy arrays). When factorizing pandas objects, the type of `uniques`
    will differ. For Categoricals, a `Categorical` is returned.

    >>> cat = pd.Categorical(['a', 'a', 'c'], categories=['a', 'b', 'c'])
    >>> codes, uniques = pd.factorize(cat)
    >>> codes
    array([0, 0, 1])
    >>> uniques
    ['a', 'c']
    Categories (3, object): ['a', 'b', 'c']

    Notice that ``'b'`` is in ``uniques.categories``, despite not being
    present in ``cat.values``.

    For all other pandas objects, an Index of the appropriate type is
    returned.

    >>> cat = pd.Series(['a', 'a', 'c'])
    >>> codes, uniques = pd.factorize(cat)
    >>> codes
    array([0, 0, 1])
    >>> uniques
    Index(['a', 'c'], dtype='object')

    If NaN is in the values, and we want to include NaN in the uniques of the
    values, it can be achieved by setting ``use_na_sentinel=False``.

    >>> values = np.array([1, 2, 1, np.nan])
    >>> codes, uniques = pd.factorize(values)  # default: use_na_sentinel=True
    >>> codes
    array([ 0,  1,  0, -1])
    >>> uniques
    array([1., 2.])

    >>> codes, uniques = pd.factorize(values, use_na_sentinel=False)
    >>> codes
    array([0, 1, 0, 2])
    >>> uniques
    array([ 1.,  2., nan])
    )r   r   r   r   N)r   )r   F)compat)r   r   r   T)r   assume_uniqueverify)rN   r,   r.   r   ru   r*   r/   freqrO   rU   rP   rM   rY   r0   r   r1   wherer   r   	safe_sortrb   )	r?   r   r   r   r]   rT   r   	null_maskr   s	            r[   r   r   b  s   p &8Y/00 LT?KKKv===FH 	6,.?@AA
K#  ))t)44wg~
++ 
))/)JJww F## 		?6<6#9#9
 VI}} ?-fl5III)Xv>>(+
 
 
w  
Gq  "+
 
 
  BBG'>r\   	ascending	normalizedropnar<   c                |    t          j        dt          t                                 t	          | |||||          S )aK  
    Compute a histogram of the counts of non-null values.

    Parameters
    ----------
    values : ndarray (1-d)
    sort : bool, default True
        Sort by values
    ascending : bool, default False
        Sort in ascending order
    normalize: bool, default False
        If True then compute a relative histogram
    bins : integer, optional
        Rather than count values, group them into half-open bins,
        convenience for pd.cut, only works with numeric data
    dropna : bool, default True
        Don't include counts of NaN

    Returns
    -------
    Series
    zupandas.value_counts is deprecated and will be removed in a future version. Use pd.Series(obj).value_counts() instead.rg   )r   r   r   binsr   )rn   ro   rp   r   value_counts_internal)r?   r   r   r   r   r   s         r[   value_countsr   /  sZ    < M	E#%%    !   r\   c                   ddl m}m} t          | dd           }|rdnd}	|ddlm}
 t          | |          r| j        } 	  |
| |d          }n"# t          $ r}t          d	          |d }~ww xY w|	                    |
          }|	|_
        ||j                                                 }|j                            d          |_        |                                }|r,|j        dk                                    r|j        dd         }t#          j        t'          |          g          }nt)          |           rp || d          j        	                    |
          }|	|_
        ||j        _
        |j        }t          |t"          j                  st#          j        |          }n{t          | t.                    rnt1          t3          | j                            } || |	                              ||                                          }| j        |j        _        |j        }nt=          | d          } t?          | |          \  }}}|j         t"          j!        k    r|                    t"          j"                  } ||          }|j         tF          k    r+|j         tH          k    r|                    tH                    }nC|j         |j         k    r3|j         dk    r(tK          j&        dtN          tQ                                 ||_
         ||||	d          }|r|)                    |          }|r||*                                z  }|S )Nr   )r;   r<   r   
proportioncount)cutT)include_lowestz+bins argument only works with numeric data.r   intervalFrF   )indexr   )levelr   r   r   zstring[pyarrow_numpy]zThe behavior of value_counts with object-dtype is deprecated. In a future version, this will *not* perform dtype inference on the resulting index. To retain the old behavior, use `result.index = result.index.infer_objects()`rg   )r   r   rG   )r   )+pandasr;   r<   getattrpandas.core.reshape.tiler   rN   _valuesr   r   r   r   notnarW   
sort_indexallilocrO   r3   r   r   rU   rP   r-   rs   rangenlevelsgroupbysizenamesru   value_counts_arraylikerM   float16ry   r   rY   rn   ro   rp   r   sort_valuesr   )r?   r   r   r   r   r   r;   r<   
index_namer   r   iierrr   countslevelskeys_idxs                      r[   r   r   ^  s          
 ..J$1<<'D000000ff%% 	$^F	TVT$777BB 	T 	T 	TIJJPSS	T //**,,-|**:66""$$  	&v~*//11 	&[1%F 3r77)$$ $F++ /	FVF///7DDFDSSFFK *FL^Ffbj11 ,F++.. %	F%//00FV$///vf55 
 "(FL^FF 'vHHHF4VVDDOD&!zRZ''{{2:.. %++CyD  TZ6%9%9jj((	TZ''I!888D "/11    "CHVF#DuEEEF 9##i#88 '&**,,&Ms   A 
A/A**A/,tuple[ArrayLike, npt.NDArray[np.int64], int]c                    | }t          |           } t          j        | ||          \  }}}t          |j                  r|r|t
          k    }||         ||         }}t          ||j        |          }|||fS )z
    Parameters
    ----------
    values : np.ndarray
    dropna : bool
    mask : np.ndarray[bool] or None, default None

    Returns
    -------
    uniques : np.ndarray
    counts : np.ndarray[np.int64]
    r   )rR   r   value_countr$   rM   r
   rb   )r?   r   r   r]   r   r   
na_counterres_keyss           r[   r   r     s     H&!!F%1&&tLLLD&*8>** 4  	44<D:vd|&D x~x@@HVZ''r\   firstkeepLiteral['first', 'last', False]c                N    t          |           } t          j        | ||          S )ax  
    Return boolean ndarray denoting duplicate values.

    Parameters
    ----------
    values : np.ndarray or ExtensionArray
        Array over which to check for duplicate values.
    keep : {'first', 'last', False}, default 'first'
        - ``first`` : Mark duplicates as ``True`` except for the first
          occurrence.
        - ``last`` : Mark duplicates as ``True`` except for the last
          occurrence.
        - False : Mark all duplicates as ``True``.
    mask : ndarray[bool], optional
        array indicating which elements to exclude from checking

    Returns
    -------
    duplicated : ndarray[bool]
    )r  r   )rR   r   
duplicated)r?   r  r   s      r[   r  r    s)    2 &!!FV$T::::r\   c                   t          | d          } | }t          | j                  r5t          |           } t	          d|           } |                     |          S t          |           } t          j        | ||          \  }}|||fS 	 t          j
        |          }n<# t          $ r/}t          j        d| t                                 Y d}~nd}~ww xY wt          ||j        |          }|S )	a  
    Returns the mode(s) of an array.

    Parameters
    ----------
    values : array-like
        Array over which to check for duplicate values.
    dropna : bool, default True
        Don't consider counts of NaN/NaT.

    Returns
    -------
    np.ndarray or ExtensionArray
    moder   r>   r   )r   r   NzUnable to sort modes: rg   )ru   r$   rM   r4   r   _moderR   r   r  rO   r   r   rn   ro   r   rb   )r?   r   r   r]   npresultres_maskr   r   s           r[   r  r    s,   " v888FH6<(( +/77&//||6|***&!!FVFFFFHh!!
78$$ 
 
 
*S**'))	
 	
 	
 	
 	
 	
 	
 	
 	

 xBBFMs   B" "
C,%CCaverageaxisr   method	na_optionpctnpt.NDArray[np.float64]c           	        t          | j                  }t          |           } | j        dk    rt	          j        | |||||          }n6| j        dk    rt	          j        | ||||||          }nt          d          |S )a  
    Rank the values along a given axis.

    Parameters
    ----------
    values : np.ndarray or ExtensionArray
        Array whose values will be ranked. The number of dimensions in this
        array must not exceed 2.
    axis : int, default 0
        Axis over which to perform rankings.
    method : {'average', 'min', 'max', 'first', 'dense'}, default 'average'
        The method by which tiebreaks are broken during the ranking.
    na_option : {'keep', 'top'}, default 'keep'
        The method by which NaNs are placed in the ranking.
        - ``keep``: rank each NaN value with a NaN ranking
        - ``top``: replace each NaN with either +/- inf so that they
                   there are ranked at the top
    ascending : bool, default True
        Whether or not the elements should be ranked in ascending order.
    pct : bool, default False
        Whether or not to the display the returned rankings in integer form
        (e.g. 1, 2, 3) or in percentile form (e.g. 0.333..., 0.666..., 1).
       )is_datetimeliketies_methodr   r  r  rH   )r  r  r  r   r  r  z&Array with ndim > 2 are not supported.)r$   rM   rR   ndimr   rank_1drank_2dr   )r?   r  r  r  r   r  r  rankss           r[   rankr  +  s    > *&,77O&!!F{a+
 
 
 
		+
 
 
 @AAALr\   indicesr   
allow_fillc                   t          | t          j        t          t          t
          f          s(t          j        dt          t                                 t          |           st          j        |           } t          |          }|r0t          || j        |                    t          | ||d|          }n|                     ||          }|S )ak	  
    Take elements from an array.

    Parameters
    ----------
    arr : array-like or scalar value
        Non array-likes (sequences/scalars without a dtype) are coerced
        to an ndarray.

        .. deprecated:: 2.1.0
            Passing an argument other than a numpy.ndarray, ExtensionArray,
            Index, or Series is deprecated.

    indices : sequence of int or one-dimensional np.ndarray of int
        Indices to be taken.
    axis : int, default 0
        The axis over which to select values.
    allow_fill : bool, default False
        How to handle negative values in `indices`.

        * False: negative values in `indices` indicate positional indices
          from the right (the default). This is similar to :func:`numpy.take`.

        * True: negative values in `indices` indicate
          missing values. These values are set to `fill_value`. Any other
          negative values raise a ``ValueError``.

    fill_value : any, optional
        Fill value to use for NA-indices when `allow_fill` is True.
        This may be ``None``, in which case the default NA value for
        the type (``self.dtype.na_value``) is used.

        For multi-dimensional `arr`, each *element* is filled with
        `fill_value`.

    Returns
    -------
    ndarray or ExtensionArray
        Same type as the input.

    Raises
    ------
    IndexError
        When `indices` is out of bounds for the array.
    ValueError
        When the indexer contains negative values other than ``-1``
        and `allow_fill` is True.

    Notes
    -----
    When `allow_fill` is False, `indices` may be whatever dimensionality
    is accepted by NumPy for `arr`.

    When `allow_fill` is True, `indices` should be 1-D.

    See Also
    --------
    numpy.take : Take elements from an array along an axis.

    Examples
    --------
    >>> import pandas as pd

    With the default ``allow_fill=False``, negative numbers indicate
    positional indices from the right.

    >>> pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1])
    array([10, 10, 30])

    Setting ``allow_fill=True`` will place `fill_value` in those positions.

    >>> pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1], allow_fill=True)
    array([10., 10., nan])

    >>> pd.api.extensions.take(np.array([10, 20, 30]), [0, 0, -1], allow_fill=True,
    ...      fill_value=-10)
    array([ 10,  10, -10])
    zpd.api.extensions.take accepting non-standard inputs is deprecated and will raise in a future version. Pass either a numpy.ndarray, ExtensionArray, Index, or Series instead.rg   T)r  r  
fill_value)r  )rN   rO   rU   r+   r,   r.   rn   ro   rp   r   r   rP   r   r6   r   r2   take)arrr  r  r  r  r   s         r[   r  r  k  s    j cBJ(98YOPP 
8 '))	
 	
 	
 	
  joo!'**G .#)D/222t
 
 

 '--Mr\   leftr   value$NumpyValueArrayLike | ExtensionArraysideLiteral['left', 'right']sorterNumpySorter | Nonenpt.NDArray[np.intp] | np.intpc                   |t          |          }t          | t          j                  r)| j        j        dv rt          |          st          |          rt          j        | j        j	                  }t          |          rt          j
        |g          nt          j
        |          }||j        k                                    r%||j        k                                    r| j        }n|j        }t          |          r)t          t          |	                    |                    }n4t!          t          t"          |          |          }nt%          |           } |                     |||          S )a  
    Find indices where elements should be inserted to maintain order.

    Find the indices into a sorted array `arr` (a) such that, if the
    corresponding elements in `value` were inserted before the indices,
    the order of `arr` would be preserved.

    Assuming that `arr` is sorted:

    ======  ================================
    `side`  returned index `i` satisfies
    ======  ================================
    left    ``arr[i-1] < value <= self[i]``
    right   ``arr[i-1] <= value < self[i]``
    ======  ================================

    Parameters
    ----------
    arr: np.ndarray, ExtensionArray, Series
        Input array. If `sorter` is None, then it must be sorted in
        ascending order, otherwise `sorter` must be an array of indices
        that sort it.
    value : array-like or scalar
        Values to insert into `arr`.
    side : {'left', 'right'}, optional
        If 'left', the index of the first suitable location found is given.
        If 'right', return the last such index.  If there is no suitable
        index, return either 0 or N (where N is the length of `self`).
    sorter : 1-D array-like, optional
        Optional array of integer indices that sort array a into ascending
        order. They are typically the result of argsort.

    Returns
    -------
    array of ints or int
        If value is array-like, array of insertion points.
        If value is scalar, a single integer.

    See Also
    --------
    numpy.searchsorted : Similar method from NumPy.
    NiurL   )r$  r&  )r   rN   rO   rU   rM   r   r   r    iinfor   r3   minr   maxr   r   r   r   r4   searchsorted)r   r"  r$  r&  r+  	value_arrrM   s          r[   r.  r.    s\   ` $V,, 	3
##2INd"" #"25"9"9 # (()3E):):OBHeW%%%	"'')) 	$yEI/E.J.J.L.L 	$ IEEOEe 	Bejj//00EET)U335AAAEE -S11 EV<<<r\   >   r   r   r~   r}   ry   rx   nc                   t          |          }t          j        }| j        }t	          |          }|rt
          j        }nt
          j        }t          |t                    r| 
                                } | j        }t          | t          j                  st          | d|j         d          rL|dk    r't          dt          |           j         d|            || |                     |                    S t#          t          |           j         d          d}| j        j        dv r+t          j        }|                     d          } t*          }d	}n?|rt          j        }n0|j        d
v r'| j        j        dv rt          j        }nt          j        }| j        }|dk    r|                     dd          } t          j        |          }t          j        | j        |          }	t=          d          gdz  }
|dk    rt=          d|          nt=          |d          |
|<   ||	t?          |
          <   | j        j        t@          v rtC          j"        | |	|||           nt=          d          gdz  }|dk    rt=          |d          nt=          d|          ||<   t?          |          }t=          d          gdz  }|dk    rt=          d|           nt=          | d          ||<   t?          |          } || |         | |                   |	|<   |r|	                    d          }	|dk    r|	dddf         }	|	S )aQ  
    difference of n between self,
    analogous to s-s.shift(n)

    Parameters
    ----------
    arr : ndarray or ExtensionArray
    n : int
        number of periods
    axis : {0, 1}
        axis to shift on
    stacklevel : int, default 3
        The stacklevel for the lost dtype warning.

    Returns
    -------
    shifted
    __r   zcannot diff z	 on axis=zK has no 'diff' method. Convert to a suitable dtype prior to calling 'diff'.Fr   rK   Tr*  )r   r   r  r   rL   NrH   )datetimelikeztimedelta64[ns])#r   rO   nanrM   r   operatorxorsubrN   r)   to_numpyrU   hasattrr   
ValueErrorr   shiftr   r   r}   rV   r
   object_r   ry   rx   r  reshapeemptyr   slicerr   _diff_specialr   diff_2d)r   r0  r  narM   is_boolopis_timedelta	orig_ndimout_arr
na_indexer_res_indexerres_indexer_lag_indexerlag_indexers                  r[   diffrM  ;  s;   ( 	AA	BIEE""G \\%&& llnn	c2:&& 
3,R[,,,-- 	qyy !SS		0B!S!ST!S!STTT2c399Q<<(((99% G G G  
 L
y~hhtnn	 
	t		
 9>...JEEJEIA~~kk"a   HUOOEhsy...G++"J)*auT1~~~U1d^^Jt!#GE*
y~&& 	c7At,GGGGG d}q(/0AvvU1d^^^5q>>TL))d}q(01AU4!___5!T??TL))!r#k"2C4DEE 2,,011A~~!!!Q$-Nr\   Index | ArrayLikerT   npt.NDArray[np.intp] | Noner   r   .AnyArrayLike | tuple[AnyArrayLike, np.ndarray]c                0   t          | t          j        t          t          f          st          d          d}t          | j        t                    s*t          j	        | d          dk    rt          |           }n	 |                                 }|                     |          }n]# t
          t          j        f$ rD | j        r+t          | d         t                     rt#          |           }nt          |           }Y nw xY w||S t%          |          st          d          t'          t          j        |                    }|s<t+          t-          |                     t+          |           k    st/          d          |at1          |           \  }}  |t+          |                     }|                    |            t'          |                    |                    }|rY|                                }	|r.|t+          |            k     |t+          |           k    z  }
d||
<   nd}
t7          |	|d	
          }nt          j        t+          |          t:                    }|                    |t          j        t+          |                               |                    |d          }|r3|d	k    }
|r+|
|t+          |            k     z  |t+          |           k    z  }
|r|
t          j         ||
d	           |t'          |          fS )a  
    Sort ``values`` and reorder corresponding ``codes``.

    ``values`` should be unique if ``codes`` is not None.
    Safe for use with mixed types (int, str), orders ints before strs.

    Parameters
    ----------
    values : list-like
        Sequence; must be unique if ``codes`` is not None.
    codes : np.ndarray[intp] or None, default None
        Indices to ``values``. All out of bound indices are treated as
        "not found" and will be masked with ``-1``.
    use_na_sentinel : bool, default True
        If True, the sentinel -1 will be used for NaN values. If False,
        NaN values will be encoded as non-negative integers and will not drop the
        NaN from the uniques of the values.
    assume_unique : bool, default False
        When True, ``values`` are assumed to be unique, which can speed up
        the calculation. Ignored when ``codes`` is None.
    verify : bool, default True
        Check if codes are out of bound for the values and put out of bound
        codes equal to ``-1``. If ``verify=False``, it is assumed there
        are no out of bound codes. Ignored when ``codes`` is None.

    Returns
    -------
    ordered : AnyArrayLike
        Sorted ``values``
    new_codes : ndarray
        Reordered ``codes``; returned when ``codes`` is not None.

    Raises
    ------
    TypeError
        * If ``values`` is not list-like or if ``codes`` is neither None
        nor list-like
        * If ``values`` cannot be sorted
    ValueError
        * If ``codes`` is not None and ``values`` contain duplicates.
    zbOnly np.ndarray, ExtensionArray, and Index objects are allowed to be passed to safe_sort as valuesNFri   rm   r   zMOnly list-like objects or None are allowed to be passed to safe_sort as codesz,values should be unique if codes is not Noner   r  rL   wrap)r  )!rN   rO   rU   r+   r,   r   rM   r(   r   rq   _sort_mixedargsortr  decimalInvalidOperationr   rr   _sort_tuplesr!   r   rP   r   r   r:  r   map_locationslookupr2   r>  r   putarangeputmask)r?   rT   r   r   r   r&  orderedr   torder2r   	new_codesreverse_indexers                r[   r   r     s   ` frz+<hGHH 
/
 
 	

 F v|^44.OF5111_DDf%%	.^^%%Fkk&))GG734 
	. 
	. 
	. { .z&)U;; . 'v..%f--
	. } 
.
 
 	
  
5 1 122E IVF^^!4!4F!C!CGHHH~
 188
FJs6{{##	$QXXg%6%677 N!! 	S[[L(Uc&kk-ABDE$KKDFEb999		(3v;;c:::FBIc&kk$:$:;;; $((V(<<	 	NB;D NuF|34V8LM (4+

9dB''''	2222s   >)B( (ADDc                L   t          j        d | D             t                    }t          j        d | D             t                    }| | z  }t          j        | |                   }t          j        | |                   }|                                d                             |          }|                                d                             |          }|                                d         }t          j        |||g          }	|                     |	          S )z3order ints before strings before nulls in 1d arraysc                8    g | ]}t          |t                    S  )rN   rd   .0xs     r[   
<listcomp>z_sort_mixed.<locals>.<listcomp>0  s"    ;;;q
1c**;;;r\   rL   c                ,    g | ]}t          |          S re  )r0   rf  s     r[   ri  z_sort_mixed.<locals>.<listcomp>1  s    111Qa111r\   r   )rO   r3   r   rU  nonzeror  concatenate)
r?   str_posnull_posnum_posstr_argsortnum_argsortstr_locsnum_locs	null_locslocss
             r[   rT  rT  .  s    h;;F;;;4HHHGx11&111>>>Hh("G*VG_--K*VG_--K  #((55H  #((55H  ""1%I>8Xy9::D;;tr\   c                b    ddl m} ddlm}  || d          \  }} ||d          }| |         S )a  
    Convert array of tuples (1d) to array of arrays (2d).
    We need to keep the columns separately as they contain different types and
    nans (can't use `np.sort` as it may fail when str and nan are mixed in a
    column as types cannot be compared).
    r   )	to_arrays)lexsort_indexerNT)orders)"pandas.core.internals.constructionrw  pandas.core.sortingrx  )r?   rw  rx  arraysr   indexers         r[   rX  rX  =  s[     =<<<<<333333	&$''IFAofT222G'?r\   lvalsArrayLike | Indexrvalsc                J   ddl m} t          j                    5  t          j        ddt
                     t          | d          }t          |d          }ddd           n# 1 swxY w Y   |                    |d	          \  }}t          j	        |j
        |j
                  } |||j        d
d          }t          | t                    r=t          |t                    r(|                     |                                          }ngt          | t                     r| j        } t          |t                     r|j        }t%          | |g          }t          |          }t'          |          }|                    |          j
        }t          j        ||          S )a  
    Extracts the union from lvals and rvals with respect to duplicates and nans in
    both arrays.

    Parameters
    ----------
    lvals: np.ndarray or ExtensionArray
        left values which is ordered in front.
    rvals: np.ndarray or ExtensionArray
        right values ordered after lvals.

    Returns
    -------
    np.ndarray or ExtensionArray
        Containing the unsorted union of both arrays.

    Notes
    -----
    Caller is responsible for ensuring lvals.dtype == rvals.dtype.
    r   r<   ignorez<The behavior of value_counts with object-dtype is deprecated)categoryFr   NrR  r   )r   rM   rG   )r   r<   rn   catch_warningsfilterwarningsrp   r   alignrO   maximumr?   r   rN   r-   appendr   r,   r   r%   r4   reindexrepeat)	r~  r  r<   l_countr_countfinal_countunique_valscombinedrepeatss	            r[   union_with_duplicatesr  L  s   . 		 	"	" 	= 	= 	J"	
 	
 	
 	

 (e<<<'e<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= }}W};;GW*W^W^<<K&GMUSSSK%'' BJum,L,L Bll5))0022eX&& 	"MEeX&& 	"ME !%00X&&4[AA!!+..5G9['***s   ?A%%A),A)	na_actionLiteral['ignore'] | Noneconvert#np.ndarray | ExtensionArray | Indexc                0  	 |dvrd| d}t          |          t          |          rit          |t                    rt	          |d          r|		fd}n<ddlm} t          |          dk    r ||t          j	                  }n ||          }t          |t                    rV|d	k    r||j                                                 }|j                            |           }t          |j        |          }|S t          |           s|                                 S |                     t$          d
          }|t'          j        |||          S t'          j        ||t-          |                              t          j                  |          S )a  
    Map values using an input mapping or function.

    Parameters
    ----------
    mapper : function, dict, or Series
        Mapping correspondence.
    na_action : {None, 'ignore'}, default None
        If 'ignore', propagate NA values, without passing them to the
        mapping correspondence.
    convert : bool, default True
        Try to find better dtype for elementwise function results. If
        False, leave as dtype=object.

    Returns
    -------
    Union[ndarray, Index, ExtensionArray]
        The output of the mapping function applied to the array.
        If the function returns a tuple with more than one element
        a MultiIndex will be returned.
    )Nr  z+na_action must either be 'ignore' or None, z was passed__missing__c                ~    t          | t                    r t          j        |           rt          j        n|          S r   )rN   floatrO   r   r4  )rh  dict_with_defaults    r[   r   zmap_array.<locals>.<lambda>  s2    0$Q..E28A;;EA  r\   r   r  rL   r  FrF   N)r  )r   r  )r:  r   rN   dictr9  r   r<   r   rO   rx   r.   r   r   get_indexerr2   r   rG   rW   rY   r   	map_infermap_infer_maskr0   rV   rE   )
r   mapperr  r  msgr<   r}  
new_valuesr?   r  s
            @r[   	map_arrayr    s   6 (((RIRRRoo
 F (fd## 	((F(F 	( !'   FF &%%%%%6{{abj999&)$$ 	  FL..001F ,**3//V^W55
s88 xxzz ZZUZ++F}VVW====!Ff!2!228!<!<g
 
 
 	
r\   )r?   r   r@   rA   )r?   r   rM   r   r]   r   r@   r   )rc   rd   r@   r   )r?   rA   )r?   rA   r@   rd   )r?   r   r@   r   r   )r   r   )r   r7   r?   r7   r@   r   )TNNN)r?   rA   r   r   r   r   r   rY   r   r   r@   r   )FTN)r   r   r   r   r   r   r@   r   )TFFNT)
r   r   r   r   r   r   r   r   r@   r<   )r?   rA   r   r   r   r   r@   r   )r  N)r?   r   r  r  r   r   r@   r   )TN)r?   r   r   r   r   r   r@   r   )r   r  r  TF)r?   r   r  r   r  rd   r  rd   r   r   r  r   r@   r  )r   FN)r  r   r  r   r  r   )r!  N)
r   r   r"  r#  r$  r%  r&  r'  r@   r(  )r   )r0  r   r  r   )NTFT)r?   rN  rT   rO  r   r   r   r   r   r   r@   rP  )r@   r   )r?   rA   r@   rA   )r~  r  r  r  r@   r  )NT)r   r   r  r  r  r   r@   r  )__doc__
__future__r   rV  r5  textwrapr   typingr   r   r   rn   numpyrO   pandas._libsr   r	   r   r
   r   pandas._typingr   r   r   r   r   r   pandas.util._decoratorsr   pandas.util._exceptionsr   pandas.core.dtypes.castr   r   pandas.core.dtypes.commonr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   pandas.core.dtypes.concatr%   pandas.core.dtypes.dtypesr&   r'   r(   r)   pandas.core.dtypes.genericr*   r+   r,   r-   r.   r/   pandas.core.dtypes.missingr0   r1   pandas.core.array_algos.taker2   pandas.core.constructionr3   r   r4   r5   pandas.core.indexersr6   r7   r8   r9   r   r:   r;   r<   pandas.core.arraysr=   r>   rR   rb   ru   Complex128HashTableComplex64HashTableFloat64HashTableFloat32HashTableUInt64HashTableUInt32HashTableUInt16HashTableUInt8HashTableInt64HashTableInt32HashTableInt16HashTableInt8HashTableStringHashTablePyObjectHashTabler   r   r   r   r   r   unique1dr   r   r   r   r   r   r   r  r  r  r  r.  r@  rM  r   rT  rX  r  r  re  r\   r[   <module>r     s    # " " " " "                 
                                ( ' ' ' ' ' 4 4 4 4 4 4                                        " 4 3 3 3 3 3                                 
 1 0 0 0 0 0         
 2 1 1 1 1 1                   
       K! K! K! K!\   B   8 ,*&&$$$"""" $& $   $   6^$ ^$ ^$B   ., , , , ,0  " X" X" X" X"z ! )-; ; ; ; ;| 6	  
	
 
 f	   0   	t t t t- ,tr 	, , , , ,b 	a a a a aL LP( ( ( ( (B -4)-; ; ; ; ;< RV) ) ) ) )\ 8 8 8 8 8F m m m m mp &,!%	Q= Q= Q= Q= Q=p JIIg g g g gf *. 3 3 3 3 3D      4+ 4+ 4+ 4+t +/	P
 P
 P
 P
 P
 P
 P
r\   