o
    ôT·jŒ×  ã                   @  sz  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 d“dd„ZVd”d d!„ZWd•d$d%„ZXejYejZej[ej\ej]ej^ej_ej`ejaejbejcejdejeejfd&œZgd–d'd(„Zhd—d)d*„Zid+d,„ Zjd˜d.d/„Zkd™dšd2d3„ZlejZmd4Znd›d8d9„Zo	:			dœd�dBdC„ZpeedDƒedEƒedFƒdG�	H	:	dždŸdKdL„ƒZq	:	H	H		:d d¡dQdR„Zr	:	H	H		:d d¡dSdT„Zs	d™d¢dVdW„Zt	X	d£d¤d[d\„Zu	d¥d¦d]d^„Zv		_	Y	:	Hd§d¨dfdg„Zw		H	d©dªdkdl„Zx	m	d«d¬dvdw„Zyh dx£Zzd­d®dzd{„Z{		:	H	:d¯d°d‚dƒ„Z|d±d„d…„Z}d²d†d‡„Z~d³d‹dŒ„Z		:d´dµd‘d’„Z€d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                 C  s@  t | tƒst| dd�} t| jƒrtt | ¡ƒS t | jtƒr/t	d| ƒ} | j
s*t| jƒS t | ¡S t | jtƒr=t	d| ƒ} | jS t| jƒrZt | tjƒrPt | ¡ d¡S t | ¡jddd�S t| jƒrdt | ¡S t| jƒrx| jjdv rst| ƒS t | ¡S t| jƒrƒt	tj| ƒS t| jƒr•|  d	¡}t	tj|ƒ}|S tj| td
�} 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<   r9   Úuint8F©Úcopy)é   é   é   Úi8©Údtype)Ú
isinstancer,   r4   r!   rK   r   ÚnpÚasarrayr%   r   Ú_hasnaÚ_ensure_dataÚ_datar&   Úcodesr   ÚndarrayÚviewÚastyper   r   Úitemsizer   r   r#   Úobject)r>   Únpvalues© rY   úY/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/pandas/core/algorithms.pyrP   j   s<   













rP   rK   r   Úoriginalr   c                 C  sP   t | tƒr| j|kr| S t |tjƒs| ¡ }|j| |d�} | S | j|d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
    rJ   FrD   )rL   r*   rK   rM   Úconstruct_array_typeÚ_from_sequencerU   )r>   rK   r[   ÚclsrY   rY   rZ   Ú_reconstruct_data¸   s   þr_   Ú	func_nameÚstrc                 C  sv   t | ttttjfƒs9|dkrtj|› d�tt	ƒ d� t
j| dd�}|dv r4t | tƒr.t| ƒ} t| ƒ} | S t | ¡} | 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)rL   r+   r-   r*   rM   rS   ÚwarningsÚwarnÚFutureWarningr   r
   Úinfer_dtypeÚtupleÚlistr   rN   )r>   r`   ÚinferredrY   rY   rZ   Ú_ensure_arraylikeÙ   s   û

ÿrq   )Ú
complex128Ú	complex64Úfloat64Úfloat32Úuint64Úuint32Úuint16rC   Úint64Úint32Úint16Úint8rh   rW   c                 C  s    t | ƒ} t| ƒ}t| }|| fS )z‰
    Parameters
    ----------
    values : np.ndarray

    Returns
    -------
    htable : HashTable subclass
    values : ndarray
    )rP   Ú_check_object_for_stringsÚ_hashtables)r>   Úndtyper   rY   rY   rZ   Ú_get_hashtable_algo  s   r€   c                 C  s&   | j j}|dkrtj| dd�rd}|S )z 
    Check if we can use string hashtable instead of object hashtable.

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

    Returns
    -------
    str
    rW   Fre   rh   )rK   Únamer
   Úis_string_array)r>   r   rY   rY   rZ   r}     s
   r}   c                 C  s   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>   rY   rY   rZ   Úunique3  s   ^r„   Úintc                 C  s8   t | ƒdkrdS t| ƒ} t |  ¡  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)ÚlenrP   rM   ÚbincountÚravelrU   Úsum)r>   ÚresultrY   rY   rZ   Únunique_ints”  s
   rŒ   Úmaskúnpt.NDArray[np.bool_] | Nonec                 C  sš   t | dd�} t| jtƒr|  ¡ S | }t| ƒ\}} |t| ƒƒ}|du r0| | ¡}t||j|ƒ}|S |j| |d�\}}t||j|ƒ}|dusFJ ‚|| d¡fS )z?See algorithms.unique for docs. Takes a mask for masked arrays.r„   ©r`   N©r�   Úbool)	rq   rL   rK   r'   r„   r€   r‡   r_   rU   )r>   r�   r[   r   ÚtableÚuniquesrY   rY   rZ   rƒ   «  s   
rƒ   i@B Úcompsr6   únpt.NDArray[np.bool_]c                 C  sÔ  t | ƒstdt| ƒj› d�ƒ‚t |ƒstdt|ƒj› d�ƒ‚t|ttttj	fƒsGt
|ƒ}t|dd�}t|ƒdkrF|jjdv rFt| ƒsFt|ƒ}nt|tƒrRt |¡}nt|ddd�}t| d	d�}t|dd
�}t|tj	ƒsp| |¡S t|jƒr|t|ƒ |¡S t|jƒrŽt|jƒsŽtj|jtd�S t|jƒr›t|| t¡ƒS t|jtƒr¬tt |¡t |¡ƒS t|ƒtkrÍt|ƒdkrÍ|jtkrÍt |ƒ !¡ rÈdd„ }ndd„ }nt"|j|jƒ}|j|dd�}|j|dd�}t#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 `ú`rb   r�   r   ÚiufcbT)rB   Úextract_rangeÚisinrA   rJ   é   c                 S  s   t  t  | |¡ ¡ t  | ¡¡S ©N)rM   Ú
logical_orr™   r‰   Úisnan)ÚcÚvrY   rY   rZ   Úf  s   zisin.<locals>.fc                 S  s   t  | |¡ ¡ S r›   )rM   r™   r‰   )ÚaÚbrY   rY   rZ   Ú<lambda>  s    zisin.<locals>.<lambda>FrD   )%r    Ú	TypeErrorÚtypeÚ__name__rL   r+   r-   r*   rM   rS   ro   rq   r‡   rK   Úkindr"   r   r,   r2   r4   r™   r#   Úpd_arrayr!   ÚzerosÚshaper‘   rU   rW   r'   rN   Ú_MINIMUM_COMP_ARR_LENr/   Úanyr   ÚhtableÚismember)r”   r>   Úorig_valuesÚcomps_arrayr    ÚcommonrY   rY   rZ   r™   É  s^   ÿÿÿÿÿ€







r™   TÚuse_na_sentinelr‘   Ú	size_hintú
int | NoneÚna_valuerW   ú'tuple[npt.NDArray[np.intp], np.ndarray]c           
      C  sf   | }| j jdv r
t}t| ƒ\}} ||pt| ƒƒ}|j| d|||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)rK   r§   r	   r€   r‡   Ú	factorizer_   r   )
r>   r²   r³   rµ   r�   r[   Ú
hash_klassr’   r“   rR   rY   rY   rZ   Úfactorize_array$  s   $
û	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           	      C  s  t | ttfƒr| j||d�S t| dd�} | }t | ttfƒr.| jdur.| j|d�\}}||fS t | tj	ƒs=| j|d�\}}n+t 
| ¡} |s_| jtkr_t| ƒ}| ¡ r_t| jdd�}t ||| ¡} t| ||d	�\}}|r{t|ƒd
kr{t|||d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)rL   r+   r-   r»   rq   r)   r.   ÚfreqrM   rS   rN   rK   rW   r/   r¬   r0   Úwherer½   r‡   Ú	safe_sortr_   )	r>   r¾   r²   r³   r[   rR   r“   Ú	null_maskrµ   rY   rY   rZ   r»   b  sB    ÿ


ý
ûr»   Ú	ascendingÚ	normalizeÚdropnar;   c                 C  s&   t jdttƒ d� t| |||||d�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.rc   )r¾   rÇ   rÈ   ÚbinsrÉ   )rj   rk   rl   r   Úvalue_counts_internal)r>   r¾   rÇ   rÈ   rÊ   rÉ   rY   rY   rZ   Úvalue_counts/  s   ûúrÌ   c              
   C  sB  ddl m}m} t| dd ƒ}|rdnd}	|d uruddlm}
 t| |ƒr&| j} z	|
| |dd�}W n ty@ } ztd	ƒ|‚d }~ww |j	|d
�}|	|_
||j ¡  }|j d¡|_| ¡ }|rl|jdk ¡ rl|jdd… }t t|ƒg¡}n˜t| ƒrš|| dd�jj	|d
�}|	|_
||j_
|j}t|tjƒs™t |¡}nst| tƒr¼tt| jƒƒ}|| |	d�j||d� ¡ }| j|j_|j}nQt| dd�} t| |ƒ\}}}|j tj!krÖ| tj"¡}||ƒ}|j t#dfv rì|j t$krì| t$¡}n|j |j k�r|j dk�rt%j&dt't(ƒ d� ||_
||||	dd�}|�r|j)|d�}|�r|| *¡  }|S )Nr   )r:   r;   r�   Ú
proportionÚcount)ÚcutT)Úinclude_lowestz+bins argument only works with numeric data.©rÉ   ÚintervalFrD   )Úindexr�   )ÚlevelrÉ   rÌ   r�   rh   zàThe 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()`rc   )rÓ   r�   rE   )rÇ   )+Úpandasr:   r;   ÚgetattrÚpandas.core.reshape.tilerÏ   rL   Ú_valuesr¤   rÌ   r�   rÓ   ÚnotnarU   Ú
sort_indexÚallÚilocrM   r2   r‡   r   rS   rN   r,   ro   ÚrangeÚnlevelsÚgroupbyÚsizeÚnamesrq   Úvalue_counts_arraylikerK   Úfloat16ru   r‘   rW   rj   rk   rl   r   Úsort_valuesrŠ   )r>   r¾   rÇ   rÈ   rÊ   rÉ   r:   r;   Ú
index_namer�   rÏ   ÚiiÚerrr‹   ÚcountsÚlevelsÚkeysÚ_ÚidxrY   rY   rZ   rË   ^  sv   

€ÿ
€

ÿý
ù	rË   ú,tuple[ArrayLike, npt.NDArray[np.int64], int]c                 C  sb   | }t | ƒ} tj| ||d�\}}}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�   )rP   r­   Úvalue_countr#   rK   r	   r_   )r>   rÉ   r�   r[   rê   rè   Ú
na_counterÚres_keysrY   rY   rZ   râ   Ã  s   

râ   ÚfirstÚkeepúLiteral['first', 'last', False]c                 C  s   t | ƒ} tj| ||d�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�   )rP   r­   Ú
duplicated)r>   rò   r�   rY   rY   rZ   rô   â  s   rô   c              
   C  s¾   t | dd�} | }t| jƒrt| ƒ} td| ƒ} | j|d�S t| ƒ} tj| ||d�\}}|dur2||fS zt	|ƒ}W n t
yU } ztjd|› �tƒ d� W Y d}~nd}~w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: rc   )rq   r#   rK   r3   r   Ú_moderP   r­   rõ   rÅ   r¤   rj   rk   r   r_   )r>   rÉ   r�   r[   ÚnpresultÚres_maskrç   r‹   rY   rY   rZ   rõ   ÿ  s*   

þ€ÿrõ   ÚaverageÚaxisr   ÚmethodÚ	na_optionÚpctúnpt.NDArray[np.float64]c              	   C  sd   t | jƒ}t| ƒ} | jdkrtj| |||||d�}|S | jdkr.tj| ||||||d�}|S tdƒ‚)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ý   rF   )rú   r   r  rÇ   rü   rý   z&Array with ndim > 2 are not supported.)r#   rK   rP   Úndimr   Úrank_1dÚrank_2dr¤   )r>   rú   rû   rü   rÇ   rý   r   ÚranksrY   rY   rZ   Úrank+  s0   

ú
óùþr  Úindicesr   Ú
allow_fillc                 C  s|   t | tjtttfƒstjdtt	ƒ d� t
| ƒst | ¡} t|ƒ}|r5t|| j| ƒ t| ||d|d�}|S | j||d�}|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])
    z­pd.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.rc   T)rú   r  Ú
fill_value)rú   )rL   rM   rS   r*   r+   r-   rj   rk   rl   r   r   rN   r   r5   rª   r1   Útake)Úarrr  rú   r  r	  r‹   rY   rY   rZ   r
  k  s"   Uû

ÿÿr
  Úleftr  Úvalueú$NumpyValueArrayLike | ExtensionArrayÚsideúLiteral['left', 'right']ÚsorterúNumpySorter | Noneúnpt.NDArray[np.intp] | np.intpc                 C  sÔ   |durt |ƒ}t| tjƒr^| jjdv r^t|ƒst|ƒr^t | jj	¡}t|ƒr-t 
|g¡nt 
|¡}||jk ¡ rD||jk ¡ rD| j}n|j}t|ƒrTtt| 	|¡ƒ}nttt|ƒ|d�}nt| ƒ} | j|||d�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ÚiurJ   )r  r  )r   rL   rM   rS   rK   r§   r   r   Úiinfor¥   r2   ÚminrÛ   Úmaxr   r…   r¨   r   r3   Úsearchsorted)r  r  r  r  r  Ú	value_arrrK   rY   rY   rZ   r  à  s&   0
ÿÿÿr  >   r|   r{   rz   ry   ru   rt   Únc                 C  sJ  t |ƒ}tj}| j}t|ƒ}|rtj}ntj}t|t	ƒr#|  
¡ } | j}t| tjƒsVt| d|j› d�ƒrL|dkrDtdt| ƒj› d|› �ƒ‚|| |  |¡ƒS tt| ƒj› d�ƒ‚d}| jjdv rktj}|  d¡} t}d	}n|rqtj}n|jd
v rƒ| jjdv r€tj}ntj}| j}|dkr�|  dd¡} t |¡}tj| j|d�}	tdƒgd }
|dkr­td|ƒnt|dƒ|
|< ||	t|
ƒ< | jjt v rËt!j"| |	|||d� nCtdƒgd }|dkrÛt|dƒntd|ƒ||< t|ƒ}tdƒgd }|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·   rI   Tr  )r|   r{   rÿ   r¸   rJ   NrF   )Údatetimelikeztimedelta64[ns])#r…   rM   ÚnanrK   r   ÚoperatorÚxorÚsubrL   r(   Úto_numpyrS   Úhasattrr¦   Ú
ValueErrorr¥   Úshiftr¤   r§   ry   rT   r	   Úobject_r�   ru   rt   r  ÚreshapeÚemptyrª   Úslicern   Ú_diff_specialr   Údiff_2d)r  r  rú   ÚnarK   Úis_boolÚopÚis_timedeltaÚ	orig_ndimÚout_arrÚ
na_indexerÚ_res_indexerÚres_indexerÚ_lag_indexerÚlag_indexerrY   rY   rZ   Údiff;  sh   
ÿ


  $

r6  úIndex | ArrayLikerR   únpt.NDArray[np.intp] | NonerÁ   rÂ   ú.AnyArrayLike | tuple[AnyArrayLike, np.ndarray]c              	   C  sð  t | tjttfƒstdƒ‚d}t | jtƒs#tj	| dd�dkr#t
| ƒ}n+z|  ¡ }|  |¡}W n ttjfyM   | jrGt | d tƒrGt| ƒ}nt
| ƒ}Y nw |du rT|S t|ƒs\tdƒ‚tt |¡ƒ}|sstt| ƒƒt| ƒksstdƒ‚|du r�t| ƒ\}} |t| ƒƒ}| | ¡ t| |¡ƒ}|r³| ¡ }	|r©|t| ƒ k |t| ƒkB }
d||
< nd}
t|	|d	d
�}n2tjt|ƒtd�}| |t t|ƒ¡¡ |j|dd�}|rå|d	k}
|rå|
|t| ƒ k B |t| ƒkB }
|rò|
duròt  ||
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 valuesNFre   ri   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	  rJ   Úwrap)rõ   )!rL   rM   rS   r*   r+   r¤   rK   r'   r
   rm   Ú_sort_mixedÚargsortr
  ÚdecimalÚInvalidOperationrà   rn   Ú_sort_tuplesr    r   rN   r‡   r„   r#  r€   Úmap_locationsÚlookupr1   r'  r…   ÚputÚarangeÚputmask)r>   rR   r²   rÁ   rÂ   r  Úorderedr¼   ÚtÚorder2r�   Ú	new_codesÚreverse_indexerrY   rY   rZ   rÅ   ¬  sb   0ÿ
ÿ

€öÿ

rÅ   c           
      C  s¢   t jdd„ | D ƒtd�}t jdd„ | D ƒtd�}| | @ }t  | | ¡}t  | | ¡}| ¡ d  |¡}| ¡ d  |¡}| ¡ d }t  |||g¡}	|  |	¡S )z3order ints before strings before nulls in 1d arraysc                 S  s   g | ]}t |tƒ‘qS rY   )rL   ra   ©Ú.0ÚxrY   rY   rZ   Ú
<listcomp>0  s    z_sort_mixed.<locals>.<listcomp>rJ   c                 S  s   g | ]}t |ƒ‘qS rY   )r/   rK  rY   rY   rZ   rN  1  s    r   )rM   r2   r‘   r=  Únonzeror
  Úconcatenate)
r>   Ústr_posÚnull_posÚnum_posÚstr_argsortÚnum_argsortÚstr_locsÚnum_locsÚ	null_locsÚlocsrY   rY   rZ   r<  .  s   
r<  c                 C  s:   ddl m} ddlm} || dƒ\}}||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.constructionrZ  Úpandas.core.sortingr[  )r>   rZ  r[  Úarraysrë   ÚindexerrY   rY   rZ   r@  =  s
   r@  ÚlvalsúArrayLike | IndexÚrvalsc           	      C  s  ddl m} t ¡ � tjddtd� t| dd�}t|dd�}W d  ƒ n1 s)w   Y  |j|dd	�\}}t 	|j
|j
¡}|||jd
dd�}t| tƒrZt|tƒrZ|  |¡ ¡ }nt| tƒrb| j} t|tƒrj|j}t| |gƒ}t|ƒ}t|ƒ}| |¡j
}t ||¡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Ñ   Nr:  r…   )rÓ   rK   rE   )rÕ   r;   rj   Úcatch_warningsÚfilterwarningsrl   rË   ÚalignrM   Úmaximumr>   rÓ   rL   r,   Úappendr„   r+   rØ   r$   r3   ÚreindexÚrepeat)	ra  rc  r;   Úl_countÚr_countÚfinal_countÚunique_valsÚcombinedÚrepeatsrY   rY   rZ   Úunion_with_duplicatesL  s0   
ý÷


rt  Ú	na_actionúLiteral['ignore'] | NoneÚconvertú#np.ndarray | ExtensionArray | Indexc           	        s
  |dvrd|› d�}t |ƒ‚t|ƒr=t|tƒr%t|dƒr%|‰ ‡ fdd„}nddlm} t|ƒdkr9||tj	d	�}n||ƒ}t|t
ƒr[|d
krM||j ¡  }|j | ¡}t|j|ƒ}|S t| ƒsc|  ¡ S | jtdd�}|du rvtj|||d�S tj||t|ƒ tj¡|d�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.
    )Nre  z+na_action must either be 'ignore' or None, z was passedÚ__missing__c                   s$   ˆ t | tƒrt | ¡rtj S |  S r›   )rL   ÚfloatrM   r�   r  )rM  ©Údict_with_defaultrY   rZ   r£   ª  s
    ÿÿzmap_array.<locals>.<lambda>r   rd  rJ   re  FrD   N)rw  )r�   rw  )r#  r   rL   Údictr"  rÕ   r;   r‡   rM   rt   r-   rÓ   rÙ   Úget_indexerr1   rØ   rE   rU   rW   r
   Ú	map_inferÚmap_infer_maskr/   rT   rC   )	r  Úmapperru  rw  Úmsgr;   r`  Ú
new_valuesr>   rY   r{  rZ   Ú	map_arrayƒ  s2   
ÿr„  )r>   r   r?   r@   )r>   r   rK   r   r[   r   r?   r   )r`   ra   r?   r   )r>   r@   )r>   r@   r?   ra   )r>   r   r?   r…   r›   )r�   rŽ   )r”   r6   r>   r6   r?   r•   )TNNN)r>   r@   r²   r‘   r³   r´   rµ   rW   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>   r@   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û   ra   rü   ra   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   )r  r…   rú   r   )NTFT)r>   r7  rR   r8  r²   r‘   rÁ   r‘   rÂ   r‘   r?   r9  )r?   r   )r>   r@   r?   r@   )ra  rb  rc  rb  r?   rb  )NT)r  r   ru  rv  rw  r‘   r?   rx  )�Ú__doc__Ú
__future__r   r>  r  Útextwrapr   Útypingr   r   r   rj   ÚnumpyrM   Ú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.missingr/   r0   Úpandas.core.array_algos.taker1   Úpandas.core.constructionr2   r¨   r3   r4   Úpandas.core.indexersr5   r6   r7   r8   rÕ   r9   r:   r;   Úpandas.core.arraysr<   r=   rP   r_   rq   Ú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)  r6  rÅ   r<  r@  rt  r„  rY   rY   rY   rZ   Ú<module>   sì     D 
	
N
!ò


a
]û>ÿÿÿñü :ú1úfÿ!ýÿ.úCûxüXsû 


:ü