
    Mh[/                      S SK Jr  S SKJrJrJrJrJr  S SKJ	r	  S SK
Jr  S SKJrJrJrJrJr  S SKrS SKrS SKJr  S SKJrJrJr  S S	KJr  S S
KJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  S SK,J-r.  S SK/J0r0J1r1J2r2  S SK3J4r4J5r5J6r6  S SK7J8r8  S SK9J:r:  S SK;J<r<J=r=J>r>J?r?J@r@JArAJBrBJCrCJDrD  S SKEJFrFJGrG  S SKHJIrIJJrJ  S SKKJLrL  S SKMJNrNJOrO  S SKPJQs  JRr  S SKSJTrT  S SKUJVrVJWrW  S SKXJYrYJZrZ  S SK[JQs  J\r]  S SK^J_r_  S SK`JQs  Jas  Jbrc  S SK`JdrdJereJfrfJgrg  S SKhJiri  S SKjJkrk  S SKlJmrmJnrn  S SKoJprpJqrq  \(       a
  S SKrJsrsJtrtJuru  \v" \cR                  5      rw\wR                  SS S!.5         " S" S#\R                  \R                  5      r{ " S$ S%\R                  \R                  5      r}S.S& jr~ " S' S\d5      rS/S( jrS0S1S) jjrS2S* jrS3S+ jrS4S5S, jjrS6S- jrg)7    )annotations)
Collection	GeneratorHashableIterableSequence)wraps	getsizeof)TYPE_CHECKINGAnyCallableLiteralcastN)
get_option)algosindexlib)
duplicated)AnyAllAnyArrayLikeAxisDropKeepDtypeObjFIgnoreRaise
IndexLabelScalarSelfShapenpt)function)InvalidIndexErrorPerformanceWarningUnsortedIndexError)Appendercache_readonlydoc)find_stack_level)coerce_indexer_dtype)	ensure_int64ensure_platform_intis_hashable
is_integeris_iteratoris_list_likeis_object_dtype	is_scalarpandas_dtype)CategoricalDtypeExtensionDtype)ABCDataFrame	ABCSeries)is_array_like)array_equivalentisna)validate_putmask)CategoricalExtensionArray)factorize_from_iterablesrecode_for_categories)sanitize_array)Index_index_shared_docsensure_indexget_unanimous_names)
FrozenList)make_invalid_op)get_group_indexlexsort_indexer)get_adjustmentpprint_thing)CategoricalIndex	DataFrameSeries
MultiIndexzMultiIndex or list of tuples)klasstarget_klassc                  6    \ rS rSrSr\R                  rS rSr	g)MultiIndexUIntEngine   zU
This class manages a MultiIndex by mapping label combinations to positive
integers.
c                    XR                   -  nUR                  S:X  a  [        R                  R	                  U5      $ [        R                  R	                  USS9$ )a  
Transform combination(s) of uint64 in one uint64 (each), in a strictly
monotonic way (i.e. respecting the lexicographic order of integer
combinations): see BaseMultiIndexCodesEngine documentation.

Parameters
----------
codes : 1- or 2-dimensional array of dtype uint64
    Combinations of integers (one per row)

Returns
-------
scalar or 1-dimensional array, of dtype uint64
    Integer(s) representing one combination (each).
   axis)offsetsndimnp
bitwise_orreduceselfcodess     K/var/www/html/env/lib/python3.13/site-packages/pandas/core/indexes/multi.py_codes_to_ints#MultiIndexUIntEngine._codes_to_ints   sN    $ 	,,
 ::?==''.. }}##E#22     N)
__name__
__module____qualname____firstlineno____doc__libindexUInt64Engine_basera   __static_attributes__rd   rc   r`   rR   rR      s    
 !!E3rc   rR   c                  6    \ rS rSrSr\R                  rS rSr	g)MultiIndexPyIntEngine   z
This class manages those (extreme) cases in which the number of possible
label combinations overflows the 64 bits integers, and uses an ObjectEngine
containing Python integers.
c                    UR                  S5      U R                  -  nUR                  S:X  a  [        R                  R                  U5      $ [        R                  R                  USS9$ )a  
Transform combination(s) of uint64 in one Python integer (each), in a
strictly monotonic way (i.e. respecting the lexicographic order of
integer combinations): see BaseMultiIndexCodesEngine documentation.

Parameters
----------
codes : 1- or 2-dimensional array of dtype uint64
    Combinations of integers (one per row)

Returns
-------
int, or 1-dimensional array of dtype object
    Integer(s) representing one combination (each).
objectrU   rV   )astyperX   rY   rZ   r[   r\   r]   s     r`   ra   $MultiIndexPyIntEngine._codes_to_ints   sY    & X&$,,6
 ::?==''.. }}##E#22rc   rd   N)
re   rf   rg   rh   ri   rj   ObjectEnginerl   ra   rm   rd   rc   r`   ro   ro      s     !!E3rc   ro   c                L   ^  [        T 5      U 4S j5       n[        [        U5      $ )zz
A decorator to allow either `name` or `names` keyword but not both.

This makes it easier to share code with base class.
c                ~   > SU;   a  SU;   a  [        S5      eSU;   a  UR                  S5      US'   T" U /UQ70 UD6$ )Nnamenamesz*Can only provide one of `names` and `name`)	TypeErrorpop)self_or_clsargskwargsmeths      r`   new_methnames_compat.<locals>.new_meth   sM    V6 1HIIV$jj0F7OK1$1&11rc   )r	   r   r   )r   r   s   ` r`   names_compatr      s*     4[2 2 8rc   c                  6  ^  \ rS rSr% Sr\R                  \" 5       -  rSr/ r	S\
S'   \" 5       r\" 5       rS/rS\
S'           S     SS jjrSS jr   S     SS jjr\S	\R(                  4     SS jj5       r\\  S       SS jj5       5       r\S	\R(                  4       SS jj5       r\  S       SS jj5       r\SS j5       r\SS j5       r\S 5       r\SS j5       rSS jr \SS j5       r!\SS j5       r"S	S
SS
S.       SS jjr#S	SS.   SS jjr$\SS j5       r%\SS j5       r&\SS  j5       r'S	S
SS
S.       SS! jjr(S	SS.   SS" jjr)\S# 5       r*\SS$ j5       r+\," \RZ                  5      \R(                  4SS% jj5       r-SS& jr.   S   SS' jjr/SSS( jjr0SSS) jjr1\," \Rd                  5      SS* j5       r2\SS+ j5       r3SS, jr4\," \Rj                  5      SSS- jj5       r5\SS. j5       r6SSS/ jjr7S0 r8S1S2.   SS3 jjr9       S             SS4 jjr:S	S5.       SS6 jjr;SS7 jr<S	SS8.SS9 jjr=\" \=\<S:S;9r>\SS< j5       r?SS= jr@\SS> j5       rA\SS? j5       rB\SS@ j5       rC\," \R                  5      SSSA jj5       rD\DrESSB jrF\," \R                  5      SSSC jj5       rGSSSD jjrHSSE jrI\," \R                  5      SSF j5       rJS\R(                  S
4     SSG jjrKSSH jrLSSI jrM\SSJ j5       rNSSSK jjrOSSL jrPSM rQSN rRSSO jrS\T" \USP   \V-  5         S       SSQ jj5       rWSR rXSSST.   SSU jjrY\T" \USV   \V-  5      SSSW jj5       rZ  S     SSX jjr[ S   SSY jjr\SSSZ jjr]SS[ jr^SS\ jr_ S   SS] jjr`SS^ jra    S         SS_ jjrbSS` jrcSSa jrdSSb jre\SSc j5       rf    SU 4Sd jjrgSU 4Se jjrhSSf jri      SSg jrjSSU 4Sh jjjrkSSSi jjrlSSj jrmSk rnSSSl jjroSSSm jjrp S   SSn jjrqSSo jrr      SSp jrsSSSq jjrtSSr jruSSs jrvSU 4St jjrwSSu jrxSSv jrySw rzSSx jr{SSy jr|Sz r}\," \R                  5      SSS{ jj5       r~S| rSS} jrSS~ jrSS jr\," \GR                  5      SSS jj5       r\GR                  r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      r\" S5      rSrU =r$ )rN      a  
A multi-level, or hierarchical, index object for pandas objects.

Parameters
----------
levels : sequence of arrays
    The unique labels for each level.
codes : sequence of arrays
    Integers for each level designating which label at each location.
sortorder : optional int
    Level of sortedness (must be lexicographically sorted by that
    level).
names : optional sequence of objects
    Names for each of the index levels. (name is accepted for compat).
copy : bool, default False
    Copy the meta-data.
verify_integrity : bool, default True
    Check that the levels/codes are consistent and valid.

Attributes
----------
names
levels
codes
nlevels
levshape
dtypes

Methods
-------
from_arrays
from_tuples
from_product
from_frame
set_levels
set_codes
to_frame
to_flat_index
sortlevel
droplevel
swaplevel
reorder_levels
remove_unused_levels
get_level_values
get_indexer
get_loc
get_locs
get_loc_level
drop

See Also
--------
MultiIndex.from_arrays  : Convert list of arrays to MultiIndex.
MultiIndex.from_product : Create a MultiIndex from the cartesian product
                          of iterables.
MultiIndex.from_tuples  : Convert list of tuples to a MultiIndex.
MultiIndex.from_frame   : Make a MultiIndex from a DataFrame.
Index : The base pandas Index type.

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

Examples
--------
A new ``MultiIndex`` is typically constructed using one of the helper
methods :meth:`MultiIndex.from_arrays`, :meth:`MultiIndex.from_product`
and :meth:`MultiIndex.from_tuples`. For example (using ``.from_arrays``):

>>> arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
>>> pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))
MultiIndex([(1,  'red'),
            (1, 'blue'),
            (2,  'red'),
            (2, 'blue')],
           names=['number', 'color'])

See further examples for how to construct a MultiIndex in the doc strings
of the mentioned helper methods.

multiindexzlist[Hashable | None]_namesry   
int | None	sortorderNFTc	                   Ub  UnUb  Uc  [        S5      e[        U5      [        U5      :w  a  [        S5      e[        U5      S:X  a  [        S5      e[        R	                  U 5      n	0 U	l        U	R                  XSS9  U	R                  X&SS9  S /[        U5      -  U	l        Ub  U	R                  U5        Ub  [        U5      U	l        OX9l        U(       a  U	R                  5       n
Xl        U	R                  5         S U	l        U	$ )NzMust pass both levels and codesz,Length of levels and codes must be the same.r   z)Must pass non-zero number of levels/codesF)copyvalidate)rz   len
ValueErrorrr   __new___cache_set_levels
_set_codesr   
_set_namesintr   _verify_integrity_codes_reset_identity_references)clslevelsr_   r   ry   dtyper   rx   verify_integrityresult	new_codess              r`   r   MultiIndex.__new__E  s    E>U]=>>v;#e*$KLLv;!HII$ 	6u=%U;V,e$ "9~F(002I%M !rc   c                    [        U5      n[        R                  " U5      (       a  [        R                  " X2   SU5      nU$ )a4  
Reassign code values as -1 if their corresponding levels are NaN.

Parameters
----------
code : list
    Code to reassign.
level : list
    Level to check for missing values (NaN, NaT, None).

Returns
-------
new code where code value = -1 if it corresponds
to a level with missing values (NaN, NaT, None).
)r:   rZ   anywhere)r^   levelcode	null_masks       r`   _validate_codesMultiIndex._validate_codest  s7      K	66) 88IOR6Drc   c                   U=(       d    U R                   nU=(       d    U R                  nUc  [        [        U5      5      n[        U5      [        U5      :w  a  [	        S5      e[        US   5      nU GH
  nX%   nX   n[        U5      U:w  a(  [	        SU Vs/ s H  n[        U5      PM     sn 35      e[        U5      (       aI  UR                  5       [        U5      :  a,  [	        SU SUR                  5        S[        U5       S35      e[        U5      (       a4  UR                  5       S:  a   [	        SU S	UR                  5        S
35      eUR                  (       a  M  [	        S[        U5       SU 35      e   U R                  bg  U R                  [        U R                   U R                  5      :  a9  [	        SU R                   S[        U R                   U R                  5       35      e/ n	[        [        U5      5       HB  nXS;   a'  U	R                  U R                  X%   X   5      5        M/  U	R                  X   5        MD     [        U	5      n
U
$ s  snf )a  
Parameters
----------
codes : optional list
    Codes to check for validity. Defaults to current codes.
levels : optional list
    Levels to check for validity. Defaults to current levels.
levels_to_validate: optional list
    Specifies the levels to verify.

Raises
------
ValueError
    If length of levels and codes don't match, if the codes for any
    level would exceed level bounds, or there are any duplicate levels.

Returns
-------
new codes where code value = -1 if it corresponds to a
NaN level.
zTLength of levels and codes must match. NOTE: this index is in an inconsistent state.r   zUnequal code lengths: z	On level z, code max (z) >= length of level (z/). NOTE: this index is in an inconsistent stater   z, code value (z) < -1zLevel values must be unique: z
 on level zQValue for sortorder must be inferior or equal to actual lexsort_depth: sortorder z with lexsort_depth )r_   r   ranger   r   maxmin	is_uniquelistr   _lexsort_depthnlevelsappendr   rE   )r^   r_   r   levels_to_verifycodes_lengthir   level_codescode_result_codesr   s              r`   r   MultiIndex._verify_integrity  sC   : #&4;;#$S[1v;#e*$:  58}!AIE(K;</ ,e-LeUc%je-L,MN  ;KOO$5U$C s,{/@.A B!%j\ *)) 
 ;KOO$5$: 9QC~koo>O=PPV!WXX??? 3DK=
1#N # "( >>%~~tzz4<< HH 004/? @**8T\\*R)SU  s6{#A$##D$8$8EH$MN##EH-	 $ |,	= .Ms   I!c                   Sn[        U5      (       d  [        U5      e[        U5      (       a  [        U5      nU H  n[        U5      (       a  M  [        U5      e   [	        S[        U5      5       H-  n[        X   5      [        XS-
     5      :w  d  M$  [        S5      e   [        U5      u  pxU[        R                  L a  U V	s/ s H  n	[        U	SS5      PM     nn	U " UUUUSS9$ s  sn	f )a  
Convert arrays to MultiIndex.

Parameters
----------
arrays : list / sequence of array-likes
    Each array-like gives one level's value for each data point.
    len(arrays) is the number of levels.
sortorder : int or None
    Level of sortedness (must be lexicographically sorted by that
    level).
names : list / sequence of str, optional
    Names for the levels in the index.

Returns
-------
MultiIndex

See Also
--------
MultiIndex.from_tuples : Convert list of tuples to MultiIndex.
MultiIndex.from_product : Make a MultiIndex from cartesian product
                          of iterables.
MultiIndex.from_frame : Make a MultiIndex from a DataFrame.

Examples
--------
>>> arrays = [[1, 1, 2, 2], ['red', 'blue', 'red', 'blue']]
>>> pd.MultiIndex.from_arrays(arrays, names=('number', 'color'))
MultiIndex([(1,  'red'),
            (1, 'blue'),
            (2,  'red'),
            (2, 'blue')],
           names=['number', 'color'])
z/Input must be a list / sequence of array-likes.rU   zall arrays must be same lengthrx   NFr   r_   r   ry   r   )r0   rz   r/   r   r   r   r   r>   r   
no_defaultgetattr)
r   arraysr   ry   	error_msgarrayr   r_   r   arrs
             r`   from_arraysMultiIndex.from_arrays  s    T F	F##I&&v&\F E&&	**  q#f+&A69~VE]!33 !ABB ' 18CNN";AB6CWS&$/6EB"
 	
 Cs   C*c                   [        U5      (       d  [        S5      e[        U5      (       a  [        U5      n[	        [
        [        [        S4      U5      n[        U5      (       at  [        S U 5       5      (       a]  [        R                  " [        U5      5      /n[        [        R                  " U[        R                  " S5      S95      /nU " UUUUSS9$ [        U5      S:X  a  Uc  [        S	5      e/ /[        U5      -  nO[!        U[        R"                  [        45      (       a_  [!        U[        5      (       a   [        R$                  " UR&                  5      n[        [(        R*                  " U5      R,                  5      nOe[!        U[        5      (       a*  [        [(        R.                  " U5      R,                  5      nO&[1        U6 n[	        [        [2        [              U5      nU R5                  XbUS
9$ )a  
Convert list of tuples to MultiIndex.

Parameters
----------
tuples : list / sequence of tuple-likes
    Each tuple is the index of one row/column.
sortorder : int or None
    Level of sortedness (must be lexicographically sorted by that
    level).
names : list / sequence of str, optional
    Names for the levels in the index.

Returns
-------
MultiIndex

See Also
--------
MultiIndex.from_arrays : Convert list of arrays to MultiIndex.
MultiIndex.from_product : Make a MultiIndex from cartesian product
                          of iterables.
MultiIndex.from_frame : Make a MultiIndex from a DataFrame.

Examples
--------
>>> tuples = [(1, 'red'), (1, 'blue'),
...           (2, 'red'), (2, 'blue')]
>>> pd.MultiIndex.from_tuples(tuples, names=('number', 'color'))
MultiIndex([(1,  'red'),
            (1, 'blue'),
            (2,  'red'),
            (2, 'blue')],
           names=['number', 'color'])
z/Input must be a list / sequence of tuple-likes..c              3  ^   #    U  H#  n[        U[        5      =(       a    U(       + v   M%     g 7fN)
isinstancetuple).0es     r`   	<genexpr>)MultiIndex.from_tuples.<locals>.<genexpr>S  s!     Nv!z!U3=A=vs   +-rr   r   Fr   r   z-Cannot infer number of levels from empty listr   ry   )r0   rz   r/   r   r   r   r   r   r   allrZ   zerosrA   comasarray_tuplesafer   r   ndarrayasarray_valuesr   tuples_to_object_arrayTto_object_array_tupleszipr   r   )r   tuplesr   ry   r_   r   r   arrss           r`   from_tuplesMultiIndex.from_tuples!  s   V F##MNNv&\Fjx}!56? v;;3NvNNNXXc&k*+EC11&@RSTUF#!&  v;!} OPP TCJ&FU 344&%((FNN3#44V<>>?F%%#44V<>>?F<D$x12D9Fv%HHrc   c                   SSK Jn  [        U5      (       d  [        S5      e[	        U5      (       a  [        U5      n[        U5      u  pVU[        R                  L a  U Vs/ s H  n[        USS5      PM     nnU" U5      nU " XeX#S9$ s  snf )ad  
Make a MultiIndex from the cartesian product of multiple iterables.

Parameters
----------
iterables : list / sequence of iterables
    Each iterable has unique labels for each level of the index.
sortorder : int or None
    Level of sortedness (must be lexicographically sorted by that
    level).
names : list / sequence of str, optional
    Names for the levels in the index.
    If not explicitly provided, names will be inferred from the
    elements of iterables if an element has a name attribute.

Returns
-------
MultiIndex

See Also
--------
MultiIndex.from_arrays : Convert list of arrays to MultiIndex.
MultiIndex.from_tuples : Convert list of tuples to MultiIndex.
MultiIndex.from_frame : Make a MultiIndex from a DataFrame.

Examples
--------
>>> numbers = [0, 1, 2]
>>> colors = ['green', 'purple']
>>> pd.MultiIndex.from_product([numbers, colors],
...                            names=['number', 'color'])
MultiIndex([(0,  'green'),
            (0, 'purple'),
            (1,  'green'),
            (1, 'purple'),
            (2,  'green'),
            (2, 'purple')],
           names=['number', 'color'])
r   )cartesian_productz-Input must be a list / sequence of iterables.rx   Nr   )
pandas.core.reshape.utilr   r0   rz   r/   r   r>   r   r   r   )r   	iterablesr   ry   r   r_   r   its           r`   from_productMultiIndex.from_productr  s    \ 	?I&&KLLy!!YI0;CNN"9BC2WR.EC "%(6ICC	 Ds   !B	c                    [        U[        5      (       d  [        S5      e[        UR	                  5       6 u  pEUc  UOUnU R                  XRUS9$ )a  
Make a MultiIndex from a DataFrame.

Parameters
----------
df : DataFrame
    DataFrame to be converted to MultiIndex.
sortorder : int, optional
    Level of sortedness (must be lexicographically sorted by that
    level).
names : list-like, optional
    If no names are provided, use the column names, or tuple of column
    names if the columns is a MultiIndex. If a sequence, overwrite
    names with the given sequence.

Returns
-------
MultiIndex
    The MultiIndex representation of the given DataFrame.

See Also
--------
MultiIndex.from_arrays : Convert list of arrays to MultiIndex.
MultiIndex.from_tuples : Convert list of tuples to MultiIndex.
MultiIndex.from_product : Make a MultiIndex from cartesian product
                          of iterables.

Examples
--------
>>> df = pd.DataFrame([['HI', 'Temp'], ['HI', 'Precip'],
...                    ['NJ', 'Temp'], ['NJ', 'Precip']],
...                   columns=['a', 'b'])
>>> df
      a       b
0    HI    Temp
1    HI  Precip
2    NJ    Temp
3    NJ  Precip

>>> pd.MultiIndex.from_frame(df)
MultiIndex([('HI',   'Temp'),
            ('HI', 'Precip'),
            ('NJ',   'Temp'),
            ('NJ', 'Precip')],
           names=['a', 'b'])

Using explicit names, instead of the column names

>>> pd.MultiIndex.from_frame(df, names=['state', 'observation'])
MultiIndex([('HI',   'Temp'),
            ('HI', 'Precip'),
            ('NJ',   'Temp'),
            ('NJ', 'Precip')],
           names=['state', 'observation'])
zInput must be a DataFramer   )r   r6   rz   r   itemsr   )r   dfr   ry   column_namescolumnss         r`   
from_frameMultiIndex.from_frame  sO    | "l++788 #RXXZ 0 %5w5IIrc   c                |   / n[        U R                  5       GH	  nU R                  U   nU R                  U   nUn[	        UR
                  [        5      (       a&  [        SU5      nUR                  R                  5       n[	        UR
                  [        5      (       d&  [        R                  " UR
                  S5      (       a  UR                  [        5      n[        R                   " U5      n["        R$                  " XTUR&                  S9nUR)                  U5        GM     [        R*                  " U5      nU$ )NrK   mM
fill_value)r   r   r   r_   r   r   r4   r   _data_internal_get_valuesr5   r   is_np_dtypers   rr   rZ   r   r   take_nd	_na_valuer   fast_zip)r^   valuesr   r   r_   valsr   s          r`   r   MultiIndex._values  s     t||$AKKNEJJqMED$**&677.5zz668$**n55

D: : {{6*::d#D==IDMM$! %$ ll6"
rc   c                    U R                   $ r   r   r^   s    r`   r   MultiIndex.values  s    ||rc   c                    [        S5      e)zv
Raises a ValueError for `MultiIndex` because there's no single
array backing a MultiIndex.

Raises
------
ValueError
zcMultiIndex has no single backing array. Use 'MultiIndex.to_numpy()' to get a NumPy array of tuples.)r   r   s    r`   r   MultiIndex.array  s     F
 	
rc   c                    SSK Jn  [        R                  " U R                   Vs/ s H  o"R
                  PM     sn5      nU" U R                   Vs/ s H  o"R                  PM     sn[        U5      S9$ s  snf s  snf )a  
Return the dtypes as a Series for the underlying MultiIndex.

Examples
--------
>>> idx = pd.MultiIndex.from_product([(0, 1, 2), ('green', 'purple')],
...                                  names=['number', 'color'])
>>> idx
MultiIndex([(0,  'green'),
            (0, 'purple'),
            (1,  'green'),
            (1, 'purple'),
            (2,  'green'),
            (2, 'purple')],
           names=['number', 'color'])
>>> idx.dtypes
number     int64
color     object
dtype: object
r   )rM   )r   )pandasrM   r   fill_missing_namesr   rx   r   rA   )r^   rM   r   ry   s       r`   dtypesMultiIndex.dtypes#  s[    , 	"&&'Lu

'LM<u{{<E%LQQ (M<s   A5A:c                2    [        U R                  S   5      $ Nr   )r   r_   r   s    r`   __len__MultiIndex.__len__>  s    4::a=!!rc   c                    [        U 5      $ )z7
Return the number of elements in the underlying data.
r   r   s    r`   sizeMultiIndex.sizeA  s     4yrc   c                    [        U R                  U R                  5       VVs/ s H  u  pUR                  US9PM     nnnU H
  nSUl        M     [        U5      $ s  snnf )a	  
Levels of the MultiIndex.

Levels refer to the different hierarchical levels or layers in a MultiIndex.
In a MultiIndex, each level represents a distinct dimension or category of
the index.

To access the levels, you can use the levels attribute of the MultiIndex,
which returns a tuple of Index objects. Each Index object represents a
level in the MultiIndex and contains the unique values found in that
specific level.

If a MultiIndex is created with levels A, B, C, and the DataFrame using
it filters out all rows of the level C, MultiIndex.levels will still
return A, B, C.

Examples
--------
>>> index = pd.MultiIndex.from_product([['mammal'],
...                                     ('goat', 'human', 'cat', 'dog')],
...                                    names=['Category', 'Animals'])
>>> leg_num = pd.DataFrame(data=(4, 2, 4, 4), index=index, columns=['Legs'])
>>> leg_num
                  Legs
Category Animals
mammal   goat        4
         human       2
         cat         4
         dog         4

>>> leg_num.index.levels
FrozenList([['mammal'], ['cat', 'dog', 'goat', 'human']])

MultiIndex levels will not change even if the DataFrame using the MultiIndex
does not contain all them anymore.
See how "human" is not in the DataFrame, but it is still in levels:

>>> large_leg_num = leg_num[leg_num.Legs > 2]
>>> large_leg_num
                  Legs
Category Animals
mammal   goat        4
         cat         4
         dog         4

>>> large_leg_num.index.levels
FrozenList([['mammal'], ['cat', 'dog', 'goat', 'human']])
rx   T)r   _levelsr   _rename_no_setting_namerE   )r^   xrx   r   r   s        r`   r   MultiIndex.levelsL  s\    j 7:$,,6TU6T71!)))&6TUE%)E"  &!!	 Vs   A)r   r   r   r   c                 ^ U(       ag  [        U5      S:X  a  [        S5      eUc$  [        U5      U R                  :w  a  [        S5      eUb#  [        U5      [        U5      :w  a  [        S5      eUc3  [        U4S jU 5       5      n[	        [        [        U5      5      5      nOnU Vs/ s H  oR                  U5      PM     nn[	        U R                  5      n	[        Xq5       H  u  p[        UTS9R                  5       X'   M!     [        U	5      nU(       a  U R                  XgS9nXl        U R                  nX`l        [        U5      (       a  U R                  U5        U R!                  5         g s  snf )Nr   z#Must set non-zero number of levels.z-Length of levels must match number of levels.z,Length of levels must match length of level.c              3  T   >#    U  H  n[        UTS 9R                  5       v   M     g7fr   N)rC   _view)r   levr   s     r`   r   )MultiIndex._set_levels.<locals>.<genexpr>  s'      $@FSt,2244s   %(r  )r   r   )r   r   r   rE   r   r   _get_level_numberr  r   rC   r  r   r   ry   r   r   _reset_cache)r^   r   r   r   r   r   
new_levelslevel_numbersr  new_levels_listlev_numr   ry   s      `         r`   r   MultiIndex._set_levels  sG    6{a !FGG}V!< !PQQ S[CJ%> !OPP=# $@F$ J !s:!78MDIJES33C8EMJ"4<<0O #M :+7$+G+M+M+O( !;#O4J..! / I $K

!u::OOE"# Ks   *E4r   r   c                  [        U[        5      (       a  O7[        U5      (       a  [        U5      nO[        U5      (       a  [	        U5      n[        X!S5      u  p!U R                  5       nUR                  5         UR                  XSUS9  U$ )a  
Set new levels on MultiIndex. Defaults to returning new index.

Parameters
----------
levels : sequence or list of sequence
    New level(s) to apply.
level : int, level name, or sequence of int/level names (default None)
    Level(s) to set (None for all levels).
verify_integrity : bool, default True
    If True, checks that levels and codes are compatible.

Returns
-------
MultiIndex

Examples
--------
>>> idx = pd.MultiIndex.from_tuples(
...     [
...         (1, "one"),
...         (1, "two"),
...         (2, "one"),
...         (2, "two"),
...         (3, "one"),
...         (3, "two")
...     ],
...     names=["foo", "bar"]
... )
>>> idx
MultiIndex([(1, 'one'),
    (1, 'two'),
    (2, 'one'),
    (2, 'two'),
    (3, 'one'),
    (3, 'two')],
   names=['foo', 'bar'])

>>> idx.set_levels([['a', 'b', 'c'], [1, 2]])
MultiIndex([('a', 1),
            ('a', 2),
            ('b', 1),
            ('b', 2),
            ('c', 1),
            ('c', 2)],
           names=['foo', 'bar'])
>>> idx.set_levels(['a', 'b', 'c'], level=0)
MultiIndex([('a', 'one'),
            ('a', 'two'),
            ('b', 'one'),
            ('b', 'two'),
            ('c', 'one'),
            ('c', 'two')],
           names=['foo', 'bar'])
>>> idx.set_levels(['a', 'b'], level='bar')
MultiIndex([(1, 'a'),
            (1, 'b'),
            (2, 'a'),
            (2, 'b'),
            (3, 'a'),
            (3, 'b')],
           names=['foo', 'bar'])

If any of the levels passed to ``set_levels()`` exceeds the
existing length, all of the values from that argument will
be stored in the MultiIndex levels, though the values will
be truncated in the MultiIndex output.

>>> idx.set_levels([['a', 'b', 'c'], [1, 2, 3, 4]], level=[0, 1])
MultiIndex([('a', 1),
    ('a', 2),
    ('b', 1),
    ('b', 2),
    ('c', 1),
    ('c', 2)],
   names=['foo', 'bar'])
>>> idx.set_levels([['a', 'b', 'c'], [1, 2, 3, 4]], level=[0, 1]).levels
FrozenList([['a', 'b', 'c'], [1, 2, 3, 4]])
LevelsT)r   r   r   )	r   rA   r8   r0   r   _require_listliker  r   r   )r^   r   r   r   idxs        r`   
set_levelsMultiIndex.set_levels  s    f fe$$6""6]F&!!&\F)%Bjjl$AQ 	 	
 
rc   c                ,    [        U R                  5      $ )z
Integer number of levels in this MultiIndex.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a'], ['b'], ['c']])
>>> mi
MultiIndex([('a', 'b', 'c')],
           )
>>> mi.nlevels
3
)r   r  r   s    r`   r   MultiIndex.nlevels  s     4<<  rc   c                :    [        S U R                   5       5      $ )z
A tuple with the length of each level.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a'], ['b'], ['c']])
>>> mi
MultiIndex([('a', 'b', 'c')],
           )
>>> mi.levshape
(1, 1, 1)
c              3  8   #    U  H  n[        U5      v   M     g 7fr   r  r   r  s     r`   r   &MultiIndex.levshape.<locals>.<genexpr>4  s     1[SVV[   )r   r   r   s    r`   levshapeMultiIndex.levshape&  s     1T[[111rc   c                    U R                   $ r   )r   r   s    r`   r_   MultiIndex.codes9      {{rc   c               p  ^ U(       aM  Uc$  [        U5      U R                  :w  a  [        S5      eUb#  [        U5      [        U5      :w  a  [        S5      eUc>  [        U4S j[	        U R
                  U5       5       5      n[        [        U5      5      nOoU Vs/ s H  oR                  U5      PM     nn[        U R                  5      n	[	        Xq5       H   u  pU R                  U
   n[        XTS9X'   M"     [        U	5      nU(       a  U R                  XgS9nX`l	        U R                  5         g s  snf )Nz+Length of codes must match number of levelsz,Length of codes must match length of levels.c              3  X   >#    U  H  u  p[        X!TS 9R                  5       v   M!     g7fr  )_coerce_indexer_frozenview)r   r  r   r   s      r`   r   (MultiIndex._set_codes.<locals>.<genexpr>N  s.      #(@$C '{dCHHJJ(@s   '*r  )r_   r   )r   r   r   rE   r   r  r   r  r   r   r   r4  r   r  )r^   r_   r   r   r   r   r   r  r  new_codes_listr  r   s      `        r`   r   MultiIndex._set_codes=  s     }Ut||!; !NOO SZ3u:%= !OPP =" #(+DLL%(@# I "#i.1MDIJES33C8EMJ!$++.N(+M(A$kk'**@4+' )B
 #>2I.. / I  ! Ks   D3c                   [        X!S5      u  p!U R                  5       nUR                  5         UR                  XUS9  U$ )a  
Set new codes on MultiIndex. Defaults to returning new index.

Parameters
----------
codes : sequence or list of sequence
    New codes to apply.
level : int, level name, or sequence of int/level names (default None)
    Level(s) to set (None for all levels).
verify_integrity : bool, default True
    If True, checks that levels and codes are compatible.

Returns
-------
new index (of same type and class...etc) or None
    The same type as the caller or None if ``inplace=True``.

Examples
--------
>>> idx = pd.MultiIndex.from_tuples(
...     [(1, "one"), (1, "two"), (2, "one"), (2, "two")], names=["foo", "bar"]
... )
>>> idx
MultiIndex([(1, 'one'),
    (1, 'two'),
    (2, 'one'),
    (2, 'two')],
   names=['foo', 'bar'])

>>> idx.set_codes([[1, 0, 1, 0], [0, 0, 1, 1]])
MultiIndex([(2, 'one'),
            (1, 'one'),
            (2, 'two'),
            (1, 'two')],
           names=['foo', 'bar'])
>>> idx.set_codes([1, 0, 1, 0], level=0)
MultiIndex([(2, 'one'),
            (1, 'two'),
            (2, 'one'),
            (1, 'two')],
           names=['foo', 'bar'])
>>> idx.set_codes([0, 0, 1, 1], level='bar')
MultiIndex([(1, 'one'),
            (1, 'one'),
            (2, 'two'),
            (2, 'two')],
           names=['foo', 'bar'])
>>> idx.set_codes([[1, 0, 1, 0], [0, 0, 1, 1]], level=[0, 1])
MultiIndex([(2, 'one'),
            (1, 'one'),
            (2, 'two'),
            (1, 'two')],
           names=['foo', 'bar'])
Codesr  )r"  r  r   r   )r^   r_   r   r   r#  s        r`   	set_codesMultiIndex.set_codesf  s@    t )w?jjlu<LM
rc   c           
        [         R                  " [         R                  " U R                   Vs/ s H  n[	        U5      [
        R                  -   PM!     sn5      5      n[         R                  " US S S2   5      S S S2   n[         R                  " USS  S//5      R                  S5      nUS   S:  a!  [        U R                  U R                  U5      $ [        U R                  U R                  U5      $ s  snf )Nr   rU   r   uint64@   )rZ   ceillog2r   r   rj   multiindex_nulls_shiftcumsumconcatenaters   ro   r_   rR   )r^   r   sizeslev_bitsrX   s        r`   _engineMultiIndex._engine  s     GGKO;;W;%Uh===;W
 99U4R4[)$B$/ ..(12,!45<<XF A;(djj'JJ#DKKWEE% Xs   &C8c                ,    [        U 5      R                  $ r   )typer   r   s    r`   _constructorMultiIndex._constructor  s    Dz%%%rc   c                x    U[         R                  La  UOU R                  n[        U 5      R	                  US US9$ )Nr   )r   r   ry   rJ  r   )r^   r   rx   ry   s       r`   _shallow_copyMultiIndex._shallow_copy  s4    CNN2

Dz%%fE%JJrc   c                    [        U 5      " U R                  U R                  U R                  U R                  SS9nU R
                  R                  5       Ul        UR
                  R                  SS 5        U$ )NFr   r   )rJ  r   r_   r   ry   r   r   r{   )r^   r   s     r`   r  MultiIndex._view  s^    d;;**nn**"
 ((*(D)rc   c                   U R                  X1US9nU(       + nSu  pVU(       a*  SSKJn  U" U R                  5      nU" U R                  5      nUb  UOU R                  nUb  UOU R                  n[        U 5      " UUU R                  USS9nU R                  R                  5       Ul        UR                  R                  SS5        U(       a  U R                  Ul	        U$ )	a  
Make a copy of this object.

Names, dtype, levels and codes can be passed and will be set on new copy.

Parameters
----------
names : sequence, optional
deep : bool, default False
name : Label
    Kept for compatibility with 1-dimensional Index. Should not be used.

Returns
-------
MultiIndex

Notes
-----
In most cases, there should be no functional difference from using
``deep``, but if ``deep`` is passed it will attempt to deepcopy.
This could be potentially expensive on large MultiIndex objects.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a'], ['b'], ['c']])
>>> mi
MultiIndex([('a', 'b', 'c')],
           )
>>> mi.copy()
MultiIndex([('a', 'b', 'c')],
           )
)rx   ry   deepNNr   )deepcopyNFr   r   )
_validate_namesr   rU  r   r_   rJ  r   r   r{   _id)	r^   ry   rS  rx   keep_idr   r_   rU  	new_indexs	            r`   r   MultiIndex.copy  s    L $$$$$G("%dkk*FTZZ(E!-4;;*

Jnn"
	  ;;++-	Xt, HHIMrc   c                    U R                   $ )z%the array interface, return my values)r   )r^   r   r   s      r`   	__array__MultiIndex.__array__   r1  rc   c                H    U R                  5       nU R                  Ul        U$ )z0this is defined as a copy with the same identity)r   rW  )r^   r   r   s      r`   r5  MultiIndex.view$  s    XX
rc   c                t    [        U5         U R                  U5        g! [        [        [        4 a     gf = f)NTF)hashget_locLookupErrorrz   r   r^   keys     r`   __contains__MultiIndex.__contains__*  s6    S		LLY
3 		s    77c                .    [         R                  " S5      $ )NO)rZ   r   r   s    r`   r   MultiIndex.dtype3  s    xx}rc   c                L   ^ SS jm[        U4S jU R                   5       5      $ )z5return a boolean if we need a qualified .info displayc                <    SU ;   =(       d    SU ;   =(       d    SU ;   $ )Nmixedstringunicoderd   r   s    r`   f0MultiIndex._is_memory_usage_qualified.<locals>.f:  s!    e#Nx5'8NI<NNrc   c              3  4   >#    U  H  nT" U5      v   M     g 7fr   rd   )r   r   rq  s     r`   r   8MultiIndex._is_memory_usage_qualified.<locals>.<genexpr>=  s     D)C1U88)Cs   returnbool)r   _inferred_type_levels)r^   rq  s    @r`   _is_memory_usage_qualified%MultiIndex._is_memory_usage_qualified7  s"    	O D)C)CDDDrc   c                $    U R                  U5      $ r   _nbytes)r^   rS  s     r`   memory_usageMultiIndex.memory_usage@  s    
 ||D!!rc   c                $    U R                  S5      $ )z1return the number of bytes in the underlying dataFr|  r   s    r`   nbytesMultiIndex.nbytesG  s     ||E""rc   c                  ^^ Sm[        U4S jU R                   5       5      n[        S U R                   5       5      n[        U4S jU R                   5       5      nX#-   U-   nXPR                  R                  TS9-  nU$ )z
return the number of bytes in the underlying data
deeply introspect the level data if deep=True

include the engine hashtable

*this is in internal routine*

   c              3  @   >#    U  H  oR                  TS 9v   M     g7f)rS  N)r~  )r   r   rS  s     r`   r   %MultiIndex._nbytes.<locals>.<genexpr>Y  s     Jk>>t>4ks   c              3  8   #    U  H  oR                   v   M     g 7fr   )r  )r   r   s     r`   r   r  Z  s     8Z88Zr,  c              3  <   >#    U  H  n[        UT5      v   M     g 7fr   r
   )r   r   objsizes     r`   r   r  [  s     E*Q9Q00*s   r  )sumr   r_   ry   rG  sizeof)r^   rS  level_nbyteslabel_nbytesnames_nbytesr   r  s    `    @r`   r}  MultiIndex._nbytesL  st     JdkkJJ8TZZ88E$**EE,|; 	,,%%4%00rc   c                    U R                    Vs/ s H  o"R                  PM     nn[        S [        X15       5       5      $ s  snf )zG
Formats each item in tup according to its level's formatter function.
c              3  6   #    U  H  u  pU" U5      v   M     g 7fr   rd   )r   funcvals      r`   r   -MultiIndex._formatter_func.<locals>.<genexpr>j  s     J0I94T#YY0Is   )r   _formatter_funcr   r   )r^   tupr   formatter_funcss       r`   r  MultiIndex._formatter_funce  s=     ?CkkJkU00kJJO0IJJJ Ks   Anan)na_repc                  / n/ n[        U R                  U R                  5       H  u  pVUR                  " SSU0UD6nUS:H  nUR	                  5       (       ag  [        U5      n	UR                  [        5      n[        R                  " Xq5      nUR                  R                  (       a   eUR                  5       nXU'   UR                  U5        UR                  U5        M     [        U5      S:X  a.  [        US   R                  US   5      5      R                  5       $ [        UUU R                   U R"                  SS9n
U
R$                  $ )Nr  r   rU   r   Fr   r_   ry   r   r   rd   )r   r   r_   _get_values_for_csvr   r   rs   strrZ   r   flags	writeabler   rA   takerN   ry   r   r   )r^   r  r~   r  r   r   r   
level_strsmask	nan_indexmis              r`   r  MultiIndex._get_values_for_csvl  s+    
	 #&dkk4::">E22K&KFKJ"$Dxxzz
O	'..s3
YYz:
&,,6666)..0$-D!j)[) #? z?aA++IaL9:NNPP !jj..!&B ::rc   c           	        [         R                  " [        U 5      R                   S3[        [        5       S9  Ub  Un[        U 5      S:X  a  / $ / n[        U R                  U R                  5       H  u  pUb  UO[        U	R                  5      n[        U	5      S:  af  U	R                  U
5      R                  US9nU
S:H  nUR                  5       (       a-  [        R                   " U["        S9nXU'   UR%                  5       nOK[&        R(                  " U	R*                  U
5       Vs/ s H  n[-        [/        U5      (       a  UOUSS9PM!     nnUR1                  U5        M     / n[        XR2                  5       Hf  u  n	n/ nU(       a  UR1                  Ub
  [-        USS9OS	5        UR5                  [        R                   " U	["        S95        UR1                  U5        Mh     Uc  [7        S
5      nU(       aX  S	n[9        U[:        5      (       d  U[<        R>                  L d   eUS[<        R>                  4;   a  Un[A        U[C        U5      US9nU(       a,  [E        5       nURF                  " U/UQ76 RI                  S5      $ U$ s  snf )Nz.format is deprecated and will be removed in a future version. Convert using index.astype(str) or index.map(formatter) instead.
stacklevelr   	formatterr   r   	
escape_chars display.multi_sparseFstartsentinelr  )%warningswarnrJ  re   FutureWarningr)   r   r   r   r_   _get_na_repr   r  formatr   rZ   r   rr   tolistr   r   r   rJ   r:   r   ry   extendr   r   rw  r   r   sparsify_labelsr   rI   adjoinsplit)r^   rx   r  r  ry   spacesparsifyr  stringified_levelsr  r   na	formattedr  r  result_levelslev_namer   r  adjs                       r`   r  MultiIndex.format  sM    	Dz""# $, , ')	
 Et9>I #DKK <C!-;syy3IB3x!|HH[18898M	 #b(88:: "& AI&(dO ) 0 0 2I #]]3;;DD !tAwwADVWD   %%i0' !=*  !3ZZ@MCE+ !8JK LL#V45  ' A !"89H;=Hh--S^^1KKKE3>>22#+SZ(M  "C::e4m4::4@@  Ms   (&Jr  c          	     0   [        U 5      S:X  a  / $ / n[        U R                  U R                  5       H  u  pV[	        UR
                  5      n[        U5      S:  aj  UR                  U5      =pUR                  SUS9n	US:H  n
U
R                  5       (       a-  [        R                  " U	[        S9n	XyU
'   U	R                  5       n	OK[        R                  " UR                  U5       Vs/ s H  n[!        [#        U5      (       a  UOUSS9PM!     n	nUR%                  U	5        M     / n[        X@R&                  5       He  u  p]/ nU(       a  UR%                  Ub
  [!        USS9OS5        UR)                  [        R                  " U[        S95        UR%                  U5        Mg     Uc  [+        S	5      nU(       aU  Sn[-        U[.        5      (       d  U[0        R2                  L d   eU[0        R2                  L a  Un[5        U[7        U5      US
9nU$ s  snf )Nr   F)include_namer  r   r   r  r  r  r  r  )r   r   r   r_   r  r   r  _format_flatr   rZ   r   rr   r  r   r   r   rJ   r:   r   ry   r  r   r   rw  r   r   r  r   )r^   include_namesr  r  r  r  r   r  takenr  r  r  r  r  r   r  s                   r`   _format_multiMultiIndex._format_multi  s    t9>I #DKK <CSYY'B3x!|$'HH[$99!..EY.W	 #b(88:: "& AI&(dO ) 0 0 2I #]]3;;DD !tAwwADVWD   %%i0) !=,  !3ZZ@MCE+ !8JK LL#V45  ' A !"89H;=Hh--S^^1KKK3>>)#+S%7(M Es   *&Hc                ,    [        U R                  5      $ r   )rE   r   r   s    r`   
_get_namesMultiIndex._get_names#  s    $++&&rc   )r   r   c               F   Ub  [        U5      (       d  [        S5      e[        U5      nU(       aM  Ub#  [        U5      [        U5      :w  a  [        S5      eUc$  [        U5      U R                  :w  a  [        S5      eUc  [        U R                  5      nO U Vs/ s H  o@R                  U5      PM     nn[        X!5       HG  u  pEUb1  [        U5      (       d!  [        [        U 5      R                   S35      eXPR                  U'   MI     U R                  5         gs  snf )a^  
Set new names on index. Each name has to be a hashable type.

Parameters
----------
values : str or sequence
    name(s) to set
level : int, level name, or sequence of int/level names (default None)
    If the index is a MultiIndex (hierarchical), level(s) to set (None
    for all levels).  Otherwise level must be None
validate : bool, default True
    validate that the names match level lengths

Raises
------
TypeError if each name is not hashable.

Notes
-----
sets names on levels. WARNING: mutates!

Note that you generally want to set this *after* changing levels, so
that it only acts on copies
Nz*Names should be list-like for a MultiIndexz+Length of names must match length of level.z:Length of names must match number of levels in MultiIndex.z.name must be a hashable type)r0   r   r   r   r   r   r  r   r-   rz   rJ  re   r   r  )r^   ry   r   r   r  rx   s         r`   r   MultiIndex._set_names&  s   6 \%%8%8IJJU SZ3u:%= !NOO}Ut||!; P  =$,,'E<ABES++C0EEB U*IC #4((#:..//LM   $KK + 	 Cs   Dam  
        Names of levels in MultiIndex.

        Examples
        --------
        >>> mi = pd.MultiIndex.from_arrays(
        ... [[1, 2], [3, 4], [5, 6]], names=['x', 'y', 'z'])
        >>> mi
        MultiIndex([(1, 3, 5),
                    (2, 4, 6)],
                   names=['x', 'y', 'z'])
        >>> mi.names
        FrozenList(['x', 'y', 'z'])
        )fsetfgetr(   c                    g)Nrm  rd   r   s    r`   inferred_typeMultiIndex.inferred_typeu  s    rc   c                    U R                   R                  U5      nUS:  a  [        U5      (       d  [        SU S35      e U R                   R	                  U5      nU$ ! [         a  n[        U5      (       d  [        SU S35      UeUS:  aE  XR                  -  nUS:  a+  XR                  -
  n[        SU R                   SU S	35      Ue S nAU$ XR                  :  a  [        SU R                   S
US-    35      Ue S nAU$ S nAff = f)NrU   z	The name z* occurs multiple times, use a level numberzLevel z
 not foundr   z Too many levels: Index has only z	 levels, z is not a valid level numberz levels, not )ry   countr.   r   r   KeyErrorr   
IndexError)r^   r   r  err
orig_levels        r`   r  MultiIndex._get_level_numbery  s<   

  'AIz%00E7"LM 	JJ$$U+E$ #  	e$$wj9:Cqy%19!&!5J$:4<<.	%,&BD    ,,& 6t||n E 19+'  '
 #	s   A 
D)A%D.DDc           
     l   [        S U R                   5       5      (       a  g[        S U R                   5       5      (       a>  [        R
                  " U R                   Vs/ s H  oR                  SSS9PM     sn5      $ [        [        [        U R                  5      5      5       Vs/ s H  o R                  U5      R                  PM     nn [        R                  " U5      n[        U5      R                  $ s  snf s  snf ! [          a"    [        U R                  5      R                  s $ f = f)z9
Return a boolean if the values are equal or increasing.
c              3  ,   #    U  H
  nS U;   v   M     g7f)r   Nrd   )r   r   s     r`   r   5MultiIndex.is_monotonic_increasing.<locals>.<genexpr>  s     1jdrTzjs   Fc              3  8   #    U  H  oR                   v   M     g 7fr   is_monotonic_increasing)r   r   s     r`   r   r    s     F+,,+r,  int64r  )r   r_   r   r   libalgosis_lexsortedrs   reversedr   r   _get_level_valuesr   rZ   lexsortrA   r  rz   )r^   r  r   r   
sort_orders        r`   r  "MultiIndex.is_monotonic_increasing  s    
 1djj111F$++FFF((8<

C
1'.
C  8@c$++FV@W7X
7X!""1%--7X 	 
	? F+J$<<< D
  	?&>>>	?s   "C=+$D*D )D32D3c                &    U SSS2   R                   $ )z9
Return a boolean if the values are equal or decreasing.
Nr   r  r   s    r`   is_monotonic_decreasing"MultiIndex.is_monotonic_decreasing  s     DbDz111rc   c                X    U R                    Vs/ s H  oR                  PM     sn$ s  snf )z7return a list of the inferred types, one for each level)r   r  )r^   r   s     r`   rx   MultiIndex._inferred_type_levels  s"     *.5A555s   'c                |    [        S U R                   5       5      n[        U R                  USSS9n[	        X15      $ )Nc              3  8   #    U  H  n[        U5      v   M     g 7fr   r  )r   r  s     r`   r   (MultiIndex.duplicated.<locals>.<genexpr>  s     6+3c#hh+r,  F)sortxnull)r   r   rG   r_   r   )r^   keepshapeidss       r`   r   MultiIndex.duplicated  s5    6$++66djj%e5I#$$rc   c                    [        S5      e)z*
fillna is not implemented for MultiIndex
z"isna is not defined for MultiIndex)NotImplementedError)r^   valuedowncasts      r`   fillnaMultiIndex.fillna  s     ""FGGrc   c                :   U R                    Vs/ s H  o"S:H  PM	     nnUS:X  a  [        R                  " USS9nO*US:X  a  [        R                  " USS9nO[	        SU 35      eU R                    Vs/ s H  o"U)    PM
     nnU R                  US9$ s  snf s  snf )Nr   r   r   rV   r   zinvalid how option: )r_   )r_   rZ   r   r   r   r;  )r^   howr   nansindexerr   s         r`   dropnaMultiIndex.dropna  s    59ZZ@Zkr!Z@%<ffT*GE\ffT*G3C59::>BjjIj{'*j	I~~I~.. A Js   B3Bc                   U R                   U   nU R                  U   nU R                  U   nU(       a  [        R                  " U5      n[        R
                  " UR                  XCR                  S9nUR                  XeS9$ )z
Return vector of label values for requested level,
equal to the length of the index

**this is an internal method**

Parameters
----------
level : int
unique : bool, default False
    if True, drop duplicated values

Returns
-------
Index
r   r  )	r   r_   r   r   uniquer   r   r   rN  )r^   r   r  r  r   rx   filleds          r`   r  MultiIndex._get_level_values  sk    " kk% jj'{{5!,,{3Ks{{KMMR   33rc   c                J    U R                  U5      nU R                  U5      nU$ )a  
Return vector of label values for requested level.

Length of returned vector is equal to the length of the index.

Parameters
----------
level : int or str
    ``level`` is either the integer position of the level in the
    MultiIndex, or the name of the level.

Returns
-------
Index
    Values is a level of this MultiIndex converted to
    a single :class:`Index` (or subclass thereof).

Notes
-----
If the level contains missing values, the result may be casted to
``float`` with missing values specified as ``NaN``. This is because
the level is converted to a regular ``Index``.

Examples
--------
Create a MultiIndex:

>>> mi = pd.MultiIndex.from_arrays((list('abc'), list('def')))
>>> mi.names = ['level_1', 'level_2']

Get level values by supplying level as either integer or name:

>>> mi.get_level_values(0)
Index(['a', 'b', 'c'], dtype='object', name='level_1')
>>> mi.get_level_values('level_2')
Index(['d', 'e', 'f'], dtype='object', name='level_2')

If a level contains missing values, the return type of the level
may be cast to ``float``.

>>> pd.MultiIndex.from_arrays([[1, None, 2], [3, 4, 5]]).dtypes
level_0    int64
level_1    int64
dtype: object
>>> pd.MultiIndex.from_arrays([[1, None, 2], [3, 4, 5]]).get_level_values(0)
Index([1.0, nan, 2.0], dtype='float64')
)r  r  )r^   r   r   s      r`   get_level_valuesMultiIndex.get_level_values  s*    ` &&u-''.rc   c                j    Uc  U R                  5       $ U R                  U5      nU R                  USS9$ )NT)r   r  )drop_duplicatesr  r  )r^   r   s     r`   r  MultiIndex.unique,  s<    =''))**51E))d)CCrc   c           	     
   SSK Jn  U[        R                  LaK  [	        U5      (       d  [        S5      e[        U5      [        U R                  5      :w  a  [        S5      eUnOU R                  5       nU(       d,  [        [        U5      5      [        U5      :w  a  [        S5      eU" [        [        U R                  5      5       Vs0 s H  ofU R                  U5      _M     snSS9nXWl        U(       a  Xl        U$ s  snf )a  
Create a DataFrame with the levels of the MultiIndex as columns.

Column ordering is determined by the DataFrame constructor with data as
a dict.

Parameters
----------
index : bool, default True
    Set the index of the returned DataFrame as the original MultiIndex.

name : list / sequence of str, optional
    The passed names should substitute index level names.

allow_duplicates : bool, optional default False
    Allow duplicate column labels to be created.

    .. versionadded:: 1.5.0

Returns
-------
DataFrame

See Also
--------
DataFrame : Two-dimensional, size-mutable, potentially heterogeneous
    tabular data.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a', 'b'], ['c', 'd']])
>>> mi
MultiIndex([('a', 'c'),
            ('b', 'd')],
           )

>>> df = mi.to_frame()
>>> df
     0  1
a c  a  c
b d  b  d

>>> df = mi.to_frame(index=False)
>>> df
   0  1
0  a  c
1  b  d

>>> df = mi.to_frame(name=['x', 'y'])
>>> df
     x  y
a c  a  c
b d  b  d
r   )rL   z1'name' must be a list / sequence of column names.z<'name' should have same length as number of levels on index.zBCannot create duplicate column labels if allow_duplicates is FalseFr  )r   rL   r   r   r0   rz   r   r   r   _get_level_namessetr   r  r   r   )r^   r   rx   allow_duplicatesrL   	idx_namesr   r   s           r`   to_frameMultiIndex.to_frame4  s    x 	%s~~%%% STT4yC,, R  I--/ICI$73y>$IT 
 ?DSEU?VW?VeD**511?VW
 #L Xs   
D c                *    [        U R                  SS9$ )aT  
Convert a MultiIndex to an Index of Tuples containing the level values.

Returns
-------
pd.Index
    Index with the MultiIndex data represented in Tuples.

See Also
--------
MultiIndex.from_tuples : Convert flat index back to MultiIndex.

Notes
-----
This method will simply return the caller if called by anything other
than a MultiIndex.

Examples
--------
>>> index = pd.MultiIndex.from_product(
...     [['foo', 'bar'], ['baz', 'qux']],
...     names=['a', 'b'])
>>> index.to_flat_index()
Index([('foo', 'baz'), ('foo', 'qux'),
       ('bar', 'baz'), ('bar', 'qux')],
      dtype='object')
F)tupleize_cols)rA   r   r   s    r`   to_flat_indexMultiIndex.to_flat_index  s    8 T\\77rc   c                4    U R                   U R                  :H  $ )a  
Return True if the codes are lexicographically sorted.

Returns
-------
bool

Examples
--------
In the below examples, the first level of the MultiIndex is sorted because
a<b<c, so there is no need to look at the next level.

>>> pd.MultiIndex.from_arrays([['a', 'b', 'c'],
...                            ['d', 'e', 'f']])._is_lexsorted()
True
>>> pd.MultiIndex.from_arrays([['a', 'b', 'c'],
...                            ['d', 'f', 'e']])._is_lexsorted()
True

In case there is a tie, the lexicographical sorting looks
at the next level of the MultiIndex.

>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'b', 'c']])._is_lexsorted()
True
>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'c', 'b']])._is_lexsorted()
False
>>> pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'],
...                            ['aa', 'bb', 'aa', 'bb']])._is_lexsorted()
True
>>> pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'],
...                            ['bb', 'aa', 'aa', 'bb']])._is_lexsorted()
False
)r   r   r   s    r`   _is_lexsortedMultiIndex._is_lexsorted  s    D ""dll22rc   c                t    U R                   b  U R                   $ [        U R                  U R                  5      $ )z}
Compute and return the lexsort_depth, the number of levels of the
MultiIndex that are sorted lexically

Returns
-------
int
)r   r   r_   r   r   s    r`   r   MultiIndex._lexsort_depth  s-     >>%>>!djj$,,77rc   c                H   U R                  5       (       a  U R                  (       a  U $ / n/ n[        U R                  U R                  5       H  u  pEUR                  (       db   UR                  5       nUR                  U5      n[        U5      n[        R                  " U[        U5      5      n[        R                  " XuSS9nUR                  U5        UR                  U5        M     [        UUU R                   U R"                  SS9$ ! [         a    U(       a  e  N[f = f)a  
This is an *internal* function.

Create a new MultiIndex from the current to monotonically sorted
items IN the levels. This does not actually make the entire MultiIndex
monotonic, JUST the levels.

The resulting MultiIndex will have the same outward
appearance, meaning the same .values and ordering. It will also
be .equals() to the original.

Returns
-------
MultiIndex

Examples
--------
>>> mi = pd.MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
...                    codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
>>> mi
MultiIndex([('a', 'bb'),
            ('a', 'aa'),
            ('b', 'bb'),
            ('b', 'aa')],
           )

>>> mi.sort_values()
MultiIndex([('a', 'aa'),
            ('a', 'bb'),
            ('b', 'aa'),
            ('b', 'bb')],
           )
r   r   F)ry   r   r   )r!  r  r   r   r_   argsortr  r,   r   get_reverse_indexerr   r   r   rz   r   rN   ry   r   )r^   raise_if_incomparabler  r   r  r   r  ris           r`   _sort_levels_monotonic!MultiIndex._sort_levels_monotonic  s   D D$@$@K
	 #DKK <C..P!kkmG
 ((7+C 2':G00#g,GB"'--B"OKc"[)# !=& **nn"
 	
 ! , -s   $DD! D!c                   / n/ nSn[        U R                  U R                  5       GH  u  pE[        R                  " [        R
                  " US-   5      S:  5      S   S-
  n[        [        U5      =(       a    US   S:H  5      n[        U5      [        U5      U-   :w  a  UR                  5       R                  5       (       a  [        U5      [        U5      :X  a    OSn[        R                  " U5      nU(       a-  [        R                  " US:H  5      S   nXhS   S/   USUS   /'   [        R                  " [        U5      U-   5      n	[        R                  " [        U5      5      U-
  X'   X   nUR                  XgS 5      nUR                  U5        UR                  U5        GM     U R!                  5       n
U(       a0  U
R#                  5         U
R%                  USS9  U
R'                  USS9  U
$ )a  
Create new MultiIndex from current that removes unused levels.

Unused level(s) means levels that are not expressed in the
labels. The resulting MultiIndex will have the same outward
appearance, meaning the same .values and ordering. It will
also be .equals() to the original.

Returns
-------
MultiIndex

Examples
--------
>>> mi = pd.MultiIndex.from_product([range(2), list('ab')])
>>> mi
MultiIndex([(0, 'a'),
            (0, 'b'),
            (1, 'a'),
            (1, 'b')],
           )

>>> mi[2:]
MultiIndex([(1, 'a'),
            (1, 'b')],
           )

The 0 from the first level is not represented
and can be removed

>>> mi2 = mi[2:].remove_unused_levels()
>>> mi2.levels
FrozenList([[1], ['a', 'b']])
FrU   r   r   TNr   )r   r   r_   rZ   r   bincountr   r   r:   r   r   r  r   aranger  r   r5  r   r   r   )r^   r  r   changedr  r   uniqueshas_nana_idxcode_mappingr   s              r`   remove_unused_levelsMultiIndex.remove_unused_levels#  s   F 
	 #DKK <C hhr{{;?;a?@CaGGW<71:+;=F7|s3x&0088:>>##GC(@  ,,{3XXgm4Q7F.5ay!n.EGQq	N+  "xxC6(9:(*		#g,(?&(H%*7 hhww/0c"[)G !=J ""$zE:i%8rc   c                    [        U R                  5      [        U R                  5      U R                  [        U R                  5      S.n[
        R                  [        U 5      U4S4$ )z*Necessary for making this object picklable)r   r_   r   ry   N)r   r   r_   r   ry   ibase
_new_IndexrJ  )r^   ds     r`   
__reduce__MultiIndex.__reduce__{  sS     4;;'$**%$**%	
 $t*a$66rc   c                   [        U5      (       a  [        R                  " U5      n/ n[        U R                  U R
                  5       HD  u  p4XA   S:X  a!  UR                  [        R                  5        M.  UR                  X4U      5        MF     [        U5      $ S n[        R                  " U5      (       a&  [        R                  " U[        S9nU R                  nOj[        U[        5      (       a*  UR                   b  UR                   S:  a  U R                  nO+[        U["        5      (       a  [        R                  " U5      nU R
                   Vs/ s H  oDU   PM	     nn[%        U R                  UU R&                  USS9$ s  snf )Nr   r   r   Fr  )r2   r   cast_scalar_indexerr   r   r_   r   rZ   r  r   is_bool_indexerr   rw  r   r   slicesteprA   rN   ry   )r^   re  retvalr  r   r   r   s          r`   __getitem__MultiIndex.__getitem__  s3   S>>))#.CF$'TZZ$@ #r)MM"&&)MM##&6"78	 %A =  I""3''jjD1 NN	C''88#sxx!| $IC''jjo=AZZHZkS)ZIH{{jj#!&  Is   Fc                    SnUR                   b  UR                   S:  a  U R                  nU R                   Vs/ s H  o3U   PM	     nn[        U 5      " U R                  UU R
                  USS9$ s  snf )z8
Fastpath for __getitem__ when we know we have a slice.
Nr   Fr  )rA  r   r_   rJ  r   r   )r^   slobjr   r   r   s        r`   _getitem_sliceMultiIndex._getitem_slice  so     	::aI;?::F:K':	FDz;;++"
 	
 Gs   A1r  c                   [         R                  " SU5        [        U5      nU R                  X4U5      nSnU R                   Vs/ s H  owR                  U5      PM     nnU(       aR  US:H  n	U	R                  5       (       a8  / n
U H.  nUnXlU	'   U
R                  [        R                  " U5      5        M0     U
n[        U R                  XR                  SS9$ s  snf )Nrd   r   Fr   r_   ry   r   )nvvalidate_taker,   _maybe_disallow_fillr_   r  r   r   rZ   r   rN   r   ry   )r^   indicesrW   
allow_fillr   r~   na_valuelabr  r  masked	new_labellabel_valuess                r`   r  MultiIndex.take  s     	V$%g. ..zwO
.2jj9js'"j9b=Dxxzz!&I#,L)1&MM"**\":; "' ;;e::PU
 	
 :s   Cc                |  ^ ^
^ [        U[        [        45      (       d  U/n[        U 4S jU 5       5      (       Ga  / n/ n/ n[	        T R
                  5       H  m
T R                  T
   nU H!  nUR                  UR                  T
   5      nM#     T /UQ Vs/ s H)  n[        UR                  T
   UR                  T
   USS9PM+     nnT R                  T
   m[        U
U4S jU 5       5      (       a  SmUR                  [        R                  " U5      5        UR                  U5        UR                  T5        M     [        X#USS9$ T R                   4[        S U 5       5      -   n[        R                  " U5      n	 [        R#                  U	5      $ s  snf ! [$        [&        4 a    [)        U	5      s $ f = f)aT  
Append a collection of Index options together.

Parameters
----------
other : Index or list/tuple of indices

Returns
-------
Index
    The combined index.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a'], ['b']])
>>> mi
MultiIndex([('a', 'b')],
           )
>>> mi.append(mi)
MultiIndex([('a', 'b'), ('a', 'b')],
           )
c              3     >#    U  H5  n[        U[        5      =(       a    UR                  TR                  :  v   M7     g 7fr   )r   rN   r   )r   or^   s     r`   r   $MultiIndex.append.<locals>.<genexpr>  s0      
OT!Z:&D199+DDus   =A Fr  c              3  F   >#    U  H  oR                   T   T:g  v   M     g 7fr   ry   )r   r  r   
level_names     r`   r   rY  	  s     A5Rxx{j05s   !N)r_   r   ry   r   c              3  8   #    U  H  oR                   v   M     g 7fr   r   r   ks     r`   r   rY  	  s     +Eu!IIur,  )r   r   r   r   r   r   r   unionr?   r_   ry   r   r   rZ   rD  rN   r   r   rz   r  rA   )r^   otherr_   r   ry   level_valuesr  r   	to_concat
new_tuplesr   r\  s   `         @@r`   r   MultiIndex.append  s   . %$//GE 
OT
 
 
 EFE4<<(#{{1~B#/#5#5biil#CL   !%~u~	  . *RYYq\<e  .	   "ZZ]
A5AAA!%JR^^K89l+Z( )  %%  \\Oe+Eu+E&EE	^^I.
	% ))*55/0 :& 	%$$	%s   0FF F;:F;last)na_positionc                   U R                  SS9nUR                  5        Vs/ s H  oUR                  PM     nn[        XaSS9$ s  snf )NT)r(  )rg  codes_given)r*  _get_codes_for_sortingr_   rH   )r^   rg  r}   r~   targetr  keyss          r`   r&  MultiIndex.argsort	  sK     ,,4,H%+%B%B%DE%Dc		%DEt$OO Fs   Arepeatc                p   [         R                  " SSU05        [        U5      n[        U R                  U R
                   Vs/ s HM  nUR                  [        R                  5      R                  [        R                  SS9R                  U5      PMO     snU R                  U R                  SS9$ s  snf )Nrd   rW   Fr  r  )rK  validate_repeatr,   rN   r   r_   r5  rZ   r   rs   intprn  ry   r   )r^   repeatsrW   r   s       r`   rn  MultiIndex.repeat!	  s    
2~. &g.;; $(::#-K   ,33BGG%3HOOPWX#- **nn"	
 		
s   AB3
c                   Ub  U R                  XU5      $ [        U[        R                  [        45      (       d*   [
        R                  " U[        R                  " S5      S9n/ nU GH*  n U R                  U5      n[        U[        5      (       a  UR                  U5        M>  [        U[        5      (       aM  UR                  b  UR                  OSnUR                  [        UR                   UR"                  U5      5        M  [
        R$                  " U5      (       aY  U R&                  S:X  a"  [(        R*                  " S[,        [/        5       S9  UR1                  5       S   nUR                  U5        GM  S[3        U5       3n[5        U5      e   U R9                  U5      $ ! [         a     GNQf = f! [6         a    US:w  a  e  GMf  f = f)	a  
Make a new :class:`pandas.MultiIndex` with the passed list of codes deleted.

Parameters
----------
codes : array-like
    Must be a list of tuples when ``level`` is not specified.
level : int or level name, default None
errors : str, default 'raise'

Returns
-------
MultiIndex

Examples
--------
>>> idx = pd.MultiIndex.from_product([(0, 1, 2), ('green', 'purple')],
...                                  names=["number", "color"])
>>> idx
MultiIndex([(0,  'green'),
            (0, 'purple'),
            (1,  'green'),
            (1, 'purple'),
            (2,  'green'),
            (2, 'purple')],
           names=['number', 'color'])
>>> idx.drop([(1, 'green'), (2, 'purple')])
MultiIndex([(0,  'green'),
            (0, 'purple'),
            (1, 'purple'),
            (2,  'green')],
           names=['number', 'color'])

We can also drop from a specific level.

>>> idx.drop('green', level='color')
MultiIndex([(0, 'purple'),
            (1, 'purple'),
            (2, 'purple')],
           names=['number', 'color'])

>>> idx.drop([1, 2], level=0)
MultiIndex([(0,  'green'),
            (0, 'purple')],
           names=['number', 'color'])
rr   r   rU   r   zYdropping on a non-lexsorted multi-index without a level parameter may impact performance.r  zunsupported indexer of type ignore)_drop_from_levelr   rZ   r   rA   r   index_labels_to_arrayr   r   rb  r   r   r@  rA  r  r   r  stopr?  r   r  r  r$   r)   nonzerorJ  AssertionErrorr  delete)	r^   r_   r   errorsindsr   locrA  msgs	            r`   dropMultiIndex.drop3	  s   h ((v>>%"**e!45511%rxx?QR  Kll;/ c3''KK$U++'*xx';388DKKcii4 @A((--**a/ P.'7'9	 ++-*CKK$8cDC(--- !6 {{4  ?  6  X% &s7   )F) .7F:'A F:	A1F:=F:)
F76F7:GGc                   [         R                  " U5      nU R                  U5      nU R                  U   nUR	                  U5      n[        U5      nSU[        R                  " US5      US:H  -  '   UR                  S   U R                  S   :X  a  SU[        R                  " US5      '   XS:H     n[        U5      S:w  a  US:w  a  [        SU S35      e[        R                  " U R                  U   U5      ) n	X	   $ )	NFr   r   Tru  zlabels z not found in level)r   rw  r  r   get_indexerr:   rZ   equalr  r   r  r   isinr_   )
r^   r_   r   r|  r   r   r   	nan_codes	not_foundr  s
             r`   rv  MultiIndex._drop_from_level	  s     ))%0""5)A""5) K	@BE*v|<=;;q>TZZ]*02F288It,-B,'	y>Q6X#5WYK/BCDD

4::a=&11zrc   c                (   [        U R                  5      n[        U R                  5      n[        U R                  5      nU R	                  U5      nU R	                  U5      nX2   X1   sX1'   X2'   XB   XA   sXA'   XB'   XR   XQ   sXQ'   XR'   [        X4USS9$ )a  
Swap level i with level j.

Calling this method does not change the ordering of the values.

Parameters
----------
i : int, str, default -2
    First level of index to be swapped. Can pass level name as string.
    Type of parameters can be mixed.
j : int, str, default -1
    Second level of index to be swapped. Can pass level name as string.
    Type of parameters can be mixed.

Returns
-------
MultiIndex
    A new MultiIndex.

See Also
--------
Series.swaplevel : Swap levels i and j in a MultiIndex.
DataFrame.swaplevel : Swap levels i and j in a MultiIndex on a
    particular axis.

Examples
--------
>>> mi = pd.MultiIndex(levels=[['a', 'b'], ['bb', 'aa']],
...                    codes=[[0, 0, 1, 1], [0, 1, 0, 1]])
>>> mi
MultiIndex([('a', 'bb'),
            ('a', 'aa'),
            ('b', 'bb'),
            ('b', 'aa')],
           )
>>> mi.swaplevel(0, 1)
MultiIndex([('bb', 'a'),
            ('aa', 'a'),
            ('bb', 'b'),
            ('aa', 'b')],
           )
FrJ  )r   r   r_   ry   r  rN   )r^   r   jr  r   	new_namess         r`   	swaplevelMultiIndex.swaplevel	  s    V $++&
$	$	""1%""1%'1}jm$
z}%.\9<"	il%.\9<"	iliRW
 	
rc   c                r    U Vs/ s H  o R                  U5      PM     nnU R                  U5      nU$ s  snf )a  
Rearrange levels using input order. May not drop or duplicate levels.

Parameters
----------
order : list of int or list of str
    List representing new level order. Reference level by number
    (position) or by key (label).

Returns
-------
MultiIndex

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([[1, 2], [3, 4]], names=['x', 'y'])
>>> mi
MultiIndex([(1, 3),
            (2, 4)],
           names=['x', 'y'])

>>> mi.reorder_levels(order=[1, 0])
MultiIndex([(3, 1),
            (4, 2)],
           names=['y', 'x'])

>>> mi.reorder_levels(order=['y', 'x'])
MultiIndex([(3, 1),
            (4, 2)],
           names=['y', 'x'])
)r  _reorder_ilevels)r^   orderr   r   s       r`   reorder_levelsMultiIndex.reorder_levels	  s<    @ 5::Eq''*E:&&u- ;s   4c                d   [        U5      U R                  :w  a$  [        SU R                   S[        U5       35      eU Vs/ s H  o R                  U   PM     nnU Vs/ s H  o R                  U   PM     nnU Vs/ s H  o R
                  U   PM     nn[        X4USS9$ s  snf s  snf s  snf )Nz2Length of order must be same as number of levels (z), got FrJ  )r   r   rz  r   r_   ry   rN   )r^   r  r   r  r   r  s         r`   r  MultiIndex._reorder_ilevels
  s    u:% DT\\N S5zl$  /44ekk!ne
4,12EqZZ]E	2,12EqZZ]E	2iRW
 	
	 522s   B# B(>B-c              #    #    [        U5      U R                  :  a%  [        S[        U5       SU R                   S35      e[        [        U5      5       H-  n[	        U R
                  U   U R                  U   X   US9v   M/     g 7f)NzLength of new_levels (z) must be <= self.nlevels ()r  )r   r   rz  r   r?   r_   r   )r^   r  r   r   s       r`   _recode_for_new_levels!MultiIndex._recode_for_new_levels
  s      z?T\\) (Z(9 :,,0LL><  s:'A'

1t{{1~z}4  (s   BBc           
         S nU R                    Vs/ s H  n[        R                  " X!" U5      SSS9PM!     sn$ s  snf )z
we are categorizing our codes by using the
available categories (all, not just observed)
excluding any missing ones (-1); this is in preparation
for sorting, where we need to disambiguate that -1 is not
a valid valid
c                    [         R                  " [        U 5      (       a'  [         R                  " U 5      R	                  5       S-   OSU R
                  S9$ )NrU   r   r   )rZ   r/  r   r   r   r   )r   s    r`   cats/MultiIndex._get_codes_for_sorting.<locals>.cats%
  sB    9936{3C3C%))+a/!'' rc   TFr-  )r_   r<   
from_codes)r^   r  r   s      r`   rj  !MultiIndex._get_codes_for_sorting
  sI    	  $zz
) "";[0A4RWX)
 	
 
s   &;c                   [        U5      (       d  U/nU Vs/ s H  oPR                  U5      PM     nnSnU Vs/ s H  oPR                  U   PM     nn[        U[        5      (       a$  [        U5      [        U5      :X  d  [        S5      eO_U(       aS  UR                  [        [        U R                  5      5       Vs/ s H  oUU;  d  M
  U R                  U   PM     sn5        OUS   n[        XrUSS9n[        U5      nU R                   V	s/ s H  oR                  U5      PM     n
n	[        U
U R                  U R                  USS9nX4$ s  snf s  snf s  snf s  sn	f )a+  
Sort MultiIndex at the requested level.

The result will respect the original ordering of the associated
factor at that level.

Parameters
----------
level : list-like, int or str, default 0
    If a string is given, must be a name of the level.
    If list-like must be names or ints of levels.
ascending : bool, default True
    False to sort in descending order.
    Can also be a list to specify a directed ordering.
sort_remaining : sort by the remaining levels after level
na_position : {'first' or 'last'}, default 'first'
    Argument 'first' puts NaNs at the beginning, 'last' puts NaNs at
    the end.

    .. versionadded:: 2.1.0

Returns
-------
sorted_index : pd.MultiIndex
    Resulting index.
indexer : np.ndarray[np.intp]
    Indices of output values in original index.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([[0, 0], [2, 1]])
>>> mi
MultiIndex([(0, 2),
            (0, 1)],
           )

>>> mi.sortlevel()
(MultiIndex([(0, 1),
            (0, 2)],
           ), array([1, 0]))

>>> mi.sortlevel(sort_remaining=False)
(MultiIndex([(0, 2),
            (0, 1)],
           ), array([0, 1]))

>>> mi.sortlevel(1)
(MultiIndex([(0, 1),
            (0, 2)],
           ), array([1, 0]))

>>> mi.sortlevel(1, ascending=False)
(MultiIndex([(0, 2),
            (0, 1)],
           ), array([0, 1]))
Nz(level must have same length as ascendingr   T)ordersrg  ri  F)r_   r   ry   r   r   )r0   r  r_   r   r   r   r   r  r   r   rH   r,   r  rN   ry   )r^   r   	ascendingsort_remainingrg  r  r   r_   r  r   r   rY  s               r`   	sortlevelMultiIndex.sortlevel0
  sZ   ~ E""GE 49
38C""3'5 	 
 	,12ESCE2i&&u:Y/ !KLL 0LL,1#dkk2B,CX,CSRWGWC,CX aI!$
 &g.BF**M*;%%g.*	M;;**"
	 !!A

 3 Y Ns   EE?	EEEc                   [        U[        5      (       dF  Uc  U nO@US:  R                  5       (       a  U R                  U5      nO [        R	                  U5      nU R                  X5      nU$ ! [
         a    Us $ f = fr  )r   rN   r   r  r   rz   _maybe_preserve_names)r^   rk  r  preserve_namess       r`   _wrap_reindex_resultMultiIndex._wrap_reindex_result
  s|    &*--Q,##%%7+"'33F;F
 ++FC ! "!M"s   A/ /A>=A>c                    U(       aT  UR                   U R                   :X  a:  UR                  U R                  :w  a   UR                  SS9nU R                  Ul        U$ )NFr  )r   ry   r   )r^   rk  r  s      r`   r   MultiIndex._maybe_preserve_names
  sE    $,,.

*[[e[,F::FLrc   c                Z    [        U5      (       a  [        U5      (       a  [        U5      eg r   )r-   r/   r#   rd  s     r`   _check_indexing_error MultiIndex._check_indexing_error
  s)    3;s#3#3 $C((	 $4rc   c                4    U R                   S   R                  $ )z1
Should integer key(s) be treated as positional?
r   )r   _should_fallback_to_positionalr   s    r`   r  )MultiIndex._should_fallback_to_positional
  s     {{1~<<<rc   c                  > Un[        U[        5      (       d  [        R                  " U5      n[	        U5      (       aA  [        US   [
        5      (       d)  U R                  U5      nU R                  XU5        X   U4$ [        TU ]%  X5      $ r  )
r   rA   r   r   r   r   _get_indexer_level_0_raise_if_missingsuper_get_indexer_strict)r^   re  	axis_namekeyarrr  	__class__s        r`   r  MultiIndex._get_indexer_strict
  s}     &%((**62Fv;;z&)U;;//7G""3;='))w*3::rc   c                  > Un[        U[        5      (       d  [        R                  " U5      n[	        U5      (       a  [        US   [
        5      (       dq  US:H  nUR                  5       (       aV  U R                  S   R                  U5      nUS:H  nUR                  5       (       a  [        XG    S35      e[        U S35      eg [        TU ]-  XU5      $ )Nr   r   z not in index)r   rA   r   r   r   r   r   r   r  r  r  r  )	r^   re  r  r  r  r  checkcmaskr  s	           r`   r  MultiIndex._raise_if_missing
  s    #u%%**3/Fv;;z&)U;; b=DxxzzA226:99;;"fm_M#BCC &788  7,S9EErc   c                    U R                   S   nU R                  S   n[        R                  " X2SS9n[	        U5      nUR                  U5      $ )zM
Optimized equivalent to `self.get_level_values(0).get_indexer_for(target)`.
r   F)r_   
categoriesr   )r   r   r<   r  rA   get_indexer_for)r^   rk  r  r_   catcis         r`   r  MultiIndex._get_indexer_level_0
  sJ     kk!nA$$55Q3Z!!&))rc   c                P    [        U[        5      (       d  U4nU R                  XS9$ )a  
For an ordered MultiIndex, compute slice bound
that corresponds to given label.

Returns leftmost (one-past-the-rightmost if `side=='right') position
of given label.

Parameters
----------
label : object or tuple of objects
side : {'left', 'right'}

Returns
-------
int
    Index of label.

Notes
-----
This method only works if level 0 index of the MultiIndex is lexsorted.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([list('abbc'), list('gefd')])

Get the locations from the leftmost 'b' in the first level
until the end of the multiindex:

>>> mi.get_slice_bound('b', side="left")
1

Like above, but if you get the locations from the rightmost
'b' in the first level and 'f' in the second level:

>>> mi.get_slice_bound(('b','f'), side="right")
3

See Also
--------
MultiIndex.get_loc : Get location for a label or a tuple of labels.
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                      sequence of such.
side)r   r   _partial_tup_index)r^   labelr  s      r`   get_slice_boundMultiIndex.get_slice_bound
  s-    ` %''HE&&u&88rc   c                $   > [         TU ]  XU5      $ )a  
For an ordered MultiIndex, compute the slice locations for input
labels.

The input labels can be tuples representing partial levels, e.g. for a
MultiIndex with 3 levels, you can pass a single value (corresponding to
the first level), or a 1-, 2-, or 3-tuple.

Parameters
----------
start : label or tuple, default None
    If None, defaults to the beginning
end : label or tuple
    If None, defaults to the end
step : int or None
    Slice step

Returns
-------
(start, end) : (int, int)

Notes
-----
This method only works if the MultiIndex is properly lexsorted. So,
if only the first 2 levels of a 3-level MultiIndex are lexsorted,
you can only pass two levels to ``.slice_locs``.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([list('abbd'), list('deff')],
...                                names=['A', 'B'])

Get the slice locations from the beginning of 'b' in the first level
until the end of the multiindex:

>>> mi.slice_locs(start='b')
(1, 4)

Like above, but stop at the end of 'b' in the first level and 'f' in
the second level:

>>> mi.slice_locs(start='b', end=('b', 'f'))
(1, 3)

See Also
--------
MultiIndex.get_loc : Get location for a label or a tuple of labels.
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                      sequence of such.
)r  
slice_locs)r^   r  endrA  r  s       r`   r  MultiIndex.slice_locs#  s    j w!%d33rc   c                   [        U5      U R                  :  a%  [        S[        U5       SU R                   S35      e[        U5      nS[        U 5      pT[        XR                  U R
                  5      n[        U5       GHW  u  nu  pn
XU nX;  ao  [        U5      (       d_   [        R                  " XUS9n[        U5      (       d  [        SU 35      eUS:X  a  US:  a  US-  nU[        R                  " XUS9-   s  $ U R                  X5      n[        U[        5      (       a"  XsS-
  :  a  UR                  nUR                   nM  XsS-
  :  a3  U[        R                  " XSS9-   nU[        R                  " XS	S9-   nGM  [        U[        5      (       a&  UR                  nU[        R                  " XUS9-   s  $ U[        R                  " XUS9-   s  $    g ! [         a  n[        SU 35      UeS nAff = f)
NKey length (z-) was greater than MultiIndex lexsort depth (r  r   r  zLevel type mismatch: rightrU   left)r   r   r%   r   r   r_   	enumerater:   r   searchsortedrz   r.   _get_loc_single_level_indexr   r@  r  rx  )r^   r  r  nr  r  zippedr_  rQ  r  r   sectionr~  r  r#  s                  r`   r  MultiIndex._partial_tup_indexZ  s   s8d)))$s3xj )''(+ 
 HD	sS++tzz2*3F*;&A&+!,G ~d3iiL,,SDAC "##&;C5$ABB7?sax1HCu11'TJJJ223<C#u%%!!e) 		hhU e00w 
  2 2v!  C''iiu11'TJJJu11'TJJJO +< ! L#&;C5$ABKLs   %G
G<(G77G<c                f    [        U5      (       a  [        U5      (       a  gUR                  U5      $ )a  
If key is NA value, location of index unify as -1.

Parameters
----------
level_index: Index
key : label

Returns
-------
loc : int
    If key is NA value, loc is -1
    Else, location of key in index.

See Also
--------
Index.get_loc : The get_loc method for (single-level) index.
r   )r2   r:   rb  )r^   level_indexre  s      r`   r  &MultiIndex._get_loc_single_level_index  s)    & S>>d3ii&&s++rc   c           	       ^  T R                  U5        U 4S jn[        U[        5      (       d  T R                  USS9nU" U5      $ [	        U5      nT R
                  U:  a  [        SU ST R
                   S35      eUT R
                  :X  a-  T R                  (       a   T R                  R                  U5      $ T R                  nUSU XS pU(       d  Sn
[	        T 5      nO T R                  X5      u  pX:X  a  [        U5      eU	(       d  [!        X5      $ ["        R$                  " S[&        [)        5       S	9  [*        R,                  " X[*        R.                  S
9n[1        U	[	        U5      5       Hk  u  p|T R2                  U   U   T R5                  T R6                  U   U5      :H  nUR9                  5       (       d  X=   n[	        U5      (       a  Mb  [        U5      e   [	        U5      X-
  :w  a  U" U5      $ [!        X5      $ ! [         a  n[        U5      UeSnAf[         a5    T R                  U[        [        T R
                  5      5      5      u  p6Us $ f = f! [         a  n[        U5      UeSnAff = f)a  
Get location for a label or a tuple of labels.

The location is returned as an integer/slice or boolean
mask.

Parameters
----------
key : label or tuple of labels (one for each level)

Returns
-------
int, slice object or boolean mask
    If the key is past the lexsort depth, the return may be a
    boolean mask array, otherwise it is always a slice or int.

See Also
--------
Index.get_loc : The get_loc method for (single-level) index.
MultiIndex.slice_locs : Get slice location given start label(s) and
                        end label(s).
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                      sequence of such.

Notes
-----
The key cannot be a slice, list of same-level labels, a boolean mask,
or a sequence of such. If you want to use those, use
:meth:`MultiIndex.get_locs` instead.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([list('abb'), list('def')])

>>> mi.get_loc('b')
slice(1, 3, None)

>>> mi.get_loc(('b', 'e'))
1
c                Z  > [        U [        R                  5      (       a  U R                  [        R                  :w  a  U $ [
        R                  " U [        T5      5      n [        U [        5      (       a  U $ [        R                  " [        T5      SS9nUR                  S5        SX'   U$ )z<convert integer indexer to boolean mask or slice if possiblerw  r   FT)r   rZ   r   r   rq  r   maybe_indices_to_slicer   r@  emptyfill)r~  r  r^   s     r`   _maybe_to_slice+MultiIndex.get_loc.<locals>._maybe_to_slice  s|    c2::..#))rww2F
,,S#d)<C#u%%
88CIV4DIIeDIKrc   r   rp  r  z) exceeds index depth (r  Nz3indexing past lexsort depth may impact performance.r  r   )r  r   r   _get_level_indexerr   r   r  r   rG  rb  rz   get_loc_levelr   r   r   r  r@  r  r  r$   r)   rZ   r/  rq  r  r_   r  r   r   )r^   re  r  r~  keylenr  _r   lead_key
follow_keyr  rx  r_  r  s   `             r`   rb  MultiIndex.get_loc  s@   R 	""3'	 #u%%))#Q)7C"3''S<<& vh&=dll^1M  T\\!dnn||++C00 "2AwB*Et9D-"oohA =3-%%A')	
 ii2773j#h-8DA::a=%)I)IA* D 88::is88sm# 9 (+3x4<'?s#WU5EWWa  -sm, ++CeDLL6I1JK
$  - sm,-s6   H $I! 
IH?II!
I<+I77I<c                .   [        U[        [        45      (       d  U R                  U5      nO U Vs/ s H  o@R                  U5      PM     nnU R	                  XS9u  pVU(       d)  [
        R                  " U5      (       a
  XUS-    nXV4$ X   nXV4$ s  snf )a)  
Get location and sliced index for requested label(s)/level(s).

Parameters
----------
key : label or sequence of labels
level : int/level name or list thereof, optional
drop_level : bool, default True
    If ``False``, the resulting index will not drop any level.

Returns
-------
tuple
    A 2-tuple where the elements :

    Element 0: int, slice object or boolean array.

    Element 1: The resulting sliced multiindex/index. If the key
    contains all levels, this will be ``None``.

See Also
--------
MultiIndex.get_loc  : Get location for a label or a tuple of labels.
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                      sequence of such.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([list('abb'), list('def')],
...                                names=['A', 'B'])

>>> mi.get_loc_level('b')
(slice(1, 3, None), Index(['e', 'f'], dtype='object', name='B'))

>>> mi.get_loc_level('e', level='B')
(array([False,  True, False]), Index(['b'], dtype='object', name='A'))

>>> mi.get_loc_level(['b', 'e'])
(1, None)
rp  rU   )r   r   r   r  _get_loc_levelr   r.   )r^   re  r   
drop_levelr  r~  r  s          r`   r  MultiIndex.get_loc_level   s    R %$//**51E<ABES++C0EEB%%c%7~~c""a( w Yw Cs   Bc                	  ^  U 4S jn[        U[        [        45      (       a  [        U5      [        U5      :w  a  [	        S5      eSn[        X!5       H\  u  pVT R                  XeS9u  px[        U[        5      (       a(  [        R                  " [        T 5      [        S9n	SX'   U	nUc  UOXG-  nM^      U" XB5      n
XJ4$ [        U[        5      (       a  [        U5      n[        U[        5      (       Ga  US:X  Ga   UT R                  S   ;   a  T R                  XS9nU" US/5      nX4$  [!        S U 5       5      (       GdQ  [        U5      T R"                  :X  a/  T R$                  (       a   T R&                  R)                  U5      S4$ T R)                  U5      n[-        [        U5      5       Vs/ s H  oU   [        SS5      :w  d  M  UPM     nn[        U5      T R"                  :X  a  [/        U5      (       a  US4$ [-        [        U5      5       Vs/ s HP  n[        X   [0        5      (       a   T R                  U   R2                  (       a  M:  X   [        SS5      :w  d  MN  UPMR     nn[        U5      T R"                  :X  a  / nX" X5      4$ Sn[5        U5       H  u  p[        U[        5      (       d  T R                  XmS9n[        U[        5      (       aj  [6        R8                  " U5      (       d%  [6        R:                  " U[        T 5      5      (       a  M  [        R                  " [        T 5      [        S9nSUU'   O.UnO+[6        R8                  " U5      (       a  M  [        S	U 35      eUc  UnM  UU-  nM     Uc  [        SS5      n[-        [        U5      5       Vs/ s H  oU   [        SS5      :w  d  M  UPM     nnX" X5      4$ T R                  XS9n[        U[0        5      (       aS  T R                  U   R2                  (       a5  T R                  U   R)                  U5      n[/        U5      (       d  UT U   4$  U" X/5      nUU4$ ! [         a
    T U   n
 XJ4$ f = f! [        [        4 a     GN[f = f! [*         a  n[+        U5      UeSnAf[         a     GN%f = fs  snf s  snf s  snf ! [         a    T U   n UU4$ f = f)
zH
get_loc_level but with `level` known to be positional, not name-based.
c                X   > TU    n[        USS9 H  nUR                  U/5      nM     U$ )z^
If level does not exist or all levels were dropped, the exception
has to be handled outside.
T)reverse)sorted_drop_level_numbers)r  r   rY  r   r^   s       r`   maybe_mi_droplevels6MultiIndex._get_loc_level.<locals>.maybe_mi_droplevels]  s9    
 WIFD1%991#>	 2 rc   z:Key for location must have same length as number of levelsNrp  r   Tr   c              3  B   #    U  H  n[        U[        5      v   M     g 7fr   )r   r@  r^  s     r`   r   ,MultiIndex._get_loc_level.<locals>.<genexpr>  s     9Sz!U++Ss   z'Expected label or tuple of labels, got )r   r   r   r   rz  r   r  r@  rZ   r   rw  r   r   r  rz   r#   r   r   r   rG  rb  r  r   r.   r  !_supports_partial_string_indexingr  r   is_null_sliceis_full_slice)r^   re  r   r  r   r  r_  r~  rY  r  r  r  r  r   ilevels	loc_levelk_indexr  result_indexs   `                  r`   r  MultiIndex._get_loc_levelW  s   
	 eeT]++3x3u:%$P  Fe/!%!4!4Q!4!Bc5))88CIT:D $DIC &FL *" )7 : c4  *Cc5!!eqj$++a.("55c5GG 3GaS AI"-- ) 9S999s8t||+ $ 4 4S 94@@ ,,s+&+CHoUoQ5tCT9T1oUw<4<</!'**&}, "'s3x!0A *363 7 7#';;q>#S#S	   FeD$&77 !0   7|t||3"$ 3G EEE %cNDA%a//$($;$;A$;$G	%i77"00;;s?P?P )3t9@ @ !) ')hhs4y&EG15GI. '0G**1-- 
 (*QRUQV(WXX")7*; +< ?#D$/G&+CHoUoQ5tCT9T1oU 3G EEE--c-?G3$$KK&HH E*2237!%(("DM11-27GD L((_  " &\:"$ 01  $ 5&sm4$   V` V   -#G}L((-s~   4Q =.Q5 0R 4R6R69R;R;*R;.S S 	S Q21Q25R	R	
R3R""R32R3SSc                d   U R                   U   nU R                  U   nX54S jn[        U[        5      (       Gaw  UR                  nUS L=(       a    US:  n UR
                  b  UR                  UR
                  5      n	OU(       a  [        U5      S-
  n	OSn	UR                  b  UR                  UR                  5      n
O:U(       a  Sn
O0[        U	[        5      (       a  [        U5      n
O[        U5      S-
  n
 [        U	[        5      (       d  [        U
[        5      (       a#  [        U	SU	5      n	[        U
SU
5      n
U" XU5      $ US:  d  U R                  S:X  d  Ub  U(       a  U
S-
  OU
S-   n
U" XU5      $ [        R                  " XYSS9n[        R                  " XZSS9n[        XU5      $ U R                  XA5      nUS:  d  U R                  S:X  aq  [        U[        5      (       a  X]R
                  :  X]R                  :  -  nU$ [         R"                  " X]:H  [$        S	9nUR'                  5       (       d  [        U5      eU$ [        U[        5      (       a?  [        R                  " X]R
                  SS9n	[        R                  " X]R                  SS9nO*[        R                  " X]SS9n	[        R                  " X]SS9nX:X  a  [        U5      e[        X5      $ ! [         aB    UR                  UR
                  UR                  UR                  5      =pU	R                  n GN2f = f)
Nc                    Ub  XC   nUb  US:X  a
  X@:  XA:  -  nO5[         R                  " XX$R                  S9n[        R                  " XF5      nUc  U$ UR                  5       nXSU'   U$ )NrU   r   )rZ   r/  r   r   r  r   )r  rx  rA  r  r_   new_indexerrs          r`   convert_indexer6MultiIndex._get_level_indexer.<locals>.convert_indexer  sq     " |tqy$~%,?IIe4{{C#jj2""llnG*GNrc   r   rU   r  rx  r  r  r  r   )r   r_   r   r@  rA  r  rb  r   rx  r  slice_indexerr   r   r   r  r  rZ   r   rw  r   )r^   re  r   r  r  r   r  rA  is_negative_stepr  rx  r   r  r#  locsr  s                   r`   r  MultiIndex._get_level_indexer  s    kk%(jj'7> 	, c5!! 88D#4/<D1H"99('//		:E%,q0EE88'&..sxx8D%Du--{+D{+a/D %'':dE+B+B
  w6tVT2&uD99d11Q6$:J &6qD1H&uD99 &&{G&&{wGQ4(( 22;DCqyD//14c5))'994xx9OPDKzz+"4DAxxzz"3-'#u%%**;		O((hhVL**;&I((H|sm#$$q  "  +88CHHchhWWzz	"s&   A)K# 	K#  K# -K# #AL/.L/c           	       ^ [        [        R                  " U5      5       VVs/ s H  u  p#U(       d  M  UPM     nnnU(       a.  US   U R                  :  a  [	        SU SU R                   35      e[        S U 5       5      (       a  [        S5      e[        U 5      mSU4S jjnSn[        U5       GHq  u  p'Sn[        R                  " U5      (       aD  [        U5      T:w  a  [        S5      e[        R                  " U5      nUc  UR                  5       nO[        U5      (       a:   U R                  XrUS	9nUc%  [        R*                  " / [        R,                  S9s  $ Oh[        R.                  " U5      (       a=  Uc7  U[        U5      S-
  :X  a%  [        R0                  " T[        R,                  S9s  $ GM	  U R                  XrUS	9nU" U5      nUc  UnGM)  Xh-  n[        R
                  " U5      (       a  GMK  [        R
                  " U5      (       d  GMi  [#        U5      e   Uc#  [        R*                  " / [        R,                  S9$ UR3                  5       S   nU R5                  X5      $ s  snnf ! [        [         ["        4 ab  n	U HQ  n
[%        U
5      (       d  U	eU R                  XUS	9nUc
  U" U5      nM2  ['        U[(        5      (       a  S
X'   MM  X-  nMS      Sn	A	GNSn	A	ff = f)aO  
Get location for a sequence of labels.

Parameters
----------
seq : label, slice, list, mask or a sequence of such
   You should use one of the above for each level.
   If a level should not be used, set it to ``slice(None)``.

Returns
-------
numpy.ndarray
    NumPy array of integers suitable for passing to iloc.

See Also
--------
MultiIndex.get_loc : Get location for a label or a tuple of labels.
MultiIndex.slice_locs : Get slice location given start label(s) and
                        end label(s).

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([list('abb'), list('def')])

>>> mi.get_locs('b')  # doctest: +SKIP
array([1, 2], dtype=int64)

>>> mi.get_locs([slice(None), ['e', 'f']])  # doctest: +SKIP
array([1, 2], dtype=int64)

>>> mi.get_locs([[True, False, True], slice('e', 'f')])  # doctest: +SKIP
array([2], dtype=int64)
r   zIMultiIndex slicing requires the index to be lexsorted: slicing on levels z, lexsort depth c              3  0   #    U  H  o[         L v   M     g 7fr   )Ellipsisr*  s     r`   r   &MultiIndex.get_locs.<locals>.<genexpr>  s     *cH}cs   z2MultiIndex does not support indexing with Ellipsisc                   > [        U [        5      (       a)  [        R                  " T[        R                  S9nSX'   U$ U $ )Nr   T)r   r@  rZ   r   bool_)r  r  r  s     r`   _to_bool_indexer-MultiIndex.get_locs.<locals>._to_bool_indexer  s7    '5)) hhq9'+$""Nrc   NzLcannot index with a boolean indexer that is not the same length as the index)r   r  Tr   rU   r   rv  npt.NDArray[np.bool_])r  r   is_true_slicesr   r%   r   r   r   r?  r   rZ   r   r   r0   r  r#   rz   r  r-   r   r@  r   rq  r  r/  ry  _reorder_indexer)r^   seqr   strue_slicesr  r  r_  lvl_indexerr  r  item_indexerpos_indexerr  s                @r`   get_locsMultiIndex.get_locs]  s   H (11C1CC1H'IO'IVaQq'IO;r?d.A.AA$(M)9$:M:M9NP 
 *c***%D  I	 15cNDA@DK""1%%q6Q;$>  !jjm?"-"2"2"4Ka8"&"9"9!g"9"VK0 & 88Bbgg66 '
 ""1%%?qCHqL'899Qbgg66 #55a'5R +;7K%&vvg266++>+>"3-'A #F ?88Bbgg..oo'*$$S66 PV *9h? 8 *1~~"%I (,'>'> (? ( '.*:<*HK'e<<8<K5'7K 8s#   I5I5-I;;K2AK--K2c                2   Sn[        U5       GH!  u  pE[        R                  " U5      (       d+  [        R                  " U5      (       d  [	        U5      (       a  O[        U5      (       ag  [        U5      S::  a  OU R                  5       (       a?  U R                  U   R                  U5      nXfS:     nUSS USS :  R                  5       nOWSnOT[        U[        5      (       a=  U R                  5       (       a%  UR                  SL=(       a    UR                  S:  nOSnOSnU(       d  GM"    O   U(       d  U$ [        U 5      nSn[        U5       GH%  u  pE[	        U5      (       a  U/n[        R                  " U5      (       a  [        R                  " U5      U   n	GO[        U5      (       a  [        U[        R                   ["        [$        [&        45      (       d  [)        US5      n[*        R,                  " U5      n[        R.                  " [        U R                  U   5      [        R0                  S9[        U R                  U   5      -  n
U R                  U   R                  U5      nXS:     n[        R                  " [        U5      5      X'   XR2                  U   U      n	O[        U[        5      (       a=  UR                  b0  UR                  S:  a   [        R                  " U5      SSS2   U   n	Op[        U[        5      (       aB  UR4                  c5  UR6                  c(  [        R.                  " U4[        R8                  S9U   n	O[        R                  " U5      U   n	U	4U-   nGM(     [        R:                  " U5      nX,   $ )	a  
Reorder an indexer of a MultiIndex (self) so that the labels are in the
same order as given in seq

Parameters
----------
seq : label/slice/list/mask or a sequence of such
indexer: a position indexer of self

Returns
-------
indexer : a sorted position indexer of self ordered as seq
FrU   r   Nr   Trd   r   )r  r   r  r?  r2   r0   r   r!  r   r  r   r   r@  rA  rZ   r/  r   r=   rA   r7   r@   r   r  onesr>  r_   r  rx  rq  r  )r^   r  r  	need_sortr   r_  k_codesr  rl  	new_orderkey_order_maplevel_indexerinds                r`   r  MultiIndex._reorder_indexer  s   ( 	cNDA  ##s':':1'='=1aq6Q;'')) #kk!n88;G%l3G!("!; @ @ BI $IAu%%%%'' !d 2 AqvvzI $I 	y/ #0 NI') cNDA||C""1%%IIaL1	a!!bjj.%%STT&q$/ALLO "DKKN(;299 MPSKKNQ ! !%A : :1 = -q.@ A/1yy]9K/L,)**Q-*@A	Au%%!&&*<!IIaL2.w7	Au%%!''/affnGGQD8A	 IIaL1	<$&D; #@ jj|rc   c                h   U(       a  U(       a  X!:  a  [        S5      eU R                  S   R                  X5      u  p4U R                  X5      u  pV[        U R                  5      nUS   X4 US'   U R                   Vs/ s H  oXV PM     n	nU	S   U-
  U	S'   [        UU	U R                  SS9$ s  snf )a+  
Slice index between two labels / tuples, return new MultiIndex.

Parameters
----------
before : label or tuple, can be partial. Default None
    None defaults to start.
after : label or tuple, can be partial. Default None
    None defaults to end.

Returns
-------
MultiIndex
    The truncated MultiIndex.

Examples
--------
>>> mi = pd.MultiIndex.from_arrays([['a', 'b', 'c'], ['x', 'y', 'z']])
>>> mi
MultiIndex([('a', 'x'), ('b', 'y'), ('c', 'z')],
           )
>>> mi.truncate(before='a', after='b')
MultiIndex([('a', 'x'), ('b', 'y')],
           )
zafter < beforer   FrJ  )r   r   r  r   r_   rN   r   )
r^   beforeafterr   r  r  r  r  r   r   s
             r`   truncateMultiIndex.truncate<  s    4 V-..{{1~((7oof4$++&
"1a*
1@D

K
,
	K |a'	!++"	
 	
 Ls   ?B/c                "   U R                  U5      (       a  g[        U[        5      (       d  g[        U 5      [        U5      :w  a  g[        U[        5      (       d7  U R                  U5      (       d  g[        U R                  UR                  5      $ U R                  UR                  :w  a  g[        U R                  5       GHH  nU R                  U   nUR                  U   nUS:H  nUS:H  n[        R                  " XV5      (       d    gX5)    nU R                  U   R                  R                  U5      nXF)    nUR                  U   R                  R                  U5      n[        U5      S:X  a  [        U5      S:X  a  M  [        U[        R                  5      (       d  UR!                  U5      (       d    gM  [        U[        R                  5      (       d  UR!                  U5      (       d    gGM6  [        Xx5      (       a  GMI    g   g)z
Determines if two MultiIndex objects have the same labeling information
(the levels themselves do not necessarily have to be the same)

See Also
--------
equal_levels
TFr   r   )is_r   rA   r   rN   _should_comparer9   r   r   r   r_   rZ   array_equalr   r  r   equals)	r^   ra  r   
self_codesother_codes	self_mask
other_maskself_valuesother_valuess	            r`   r2  MultiIndex.equalsi  s    88E??%''t9E
"%,,''..#DLL%--@@<<5==(t||$AAJ++a.K"b(I$*J>>)88#J/J++a.0055jAK%k2K <<?2277DL ;1$\):a)?k2::66")),77  8bjj99#**;77  8 (BB = %@ rc   c                    U R                   UR                   :w  a  g[        U R                   5       H5  nU R                  U   R                  UR                  U   5      (       a  M5    g   g)zD
Return True if the levels of both MultiIndex objects are the same

FT)r   r   r   r2  )r^   ra  r   s      r`   equal_levelsMultiIndex.equal_levels  sS    
 <<5==(t||$A;;q>((a99 % rc   c                  > U R                  U5      u  pUR                  (       aA  [        TU ]  X5      n[	        U[
        5      (       a  U$ [
        R                  [        U6 S US9$ UR                  U SS9n[        U5      (       a  U R                  U5      nOU R                  U5      nUSLa   UR                  5       nU$ U$ ! [         a,    USL a  e [        R                  " S[         [#        5       S9   U$ f = f)Nr   Fr  TzTThe values in the array are unorderable. Pass `sort=False` to suppress this warning.r  )_convert_can_do_setophas_duplicatesr  _unionr   rN   r   r   
differencer   r   _get_reconciled_name_objectsort_valuesrz   r  r  RuntimeWarningr)   )r^   ra  r  result_namesr   right_missingr  s         r`   rA  MultiIndex._union  s   "88? W^E0F&*--))VL *  
 ",,T,>M=!!]399%@5 
#//1F M6M ! t|MMF&#3#5	 Ms   0C 2C:9C:c                    [        U5      $ r   )r1   )r^   r   s     r`   _is_comparable_dtypeMultiIndex._is_comparable_dtype  s    u%%rc   c                j    U R                  U5      nU R                  U:w  a  U R                  U5      $ U $ )z
If the result of a set operation will be self,
return self, unless the names change, in which
case make a shallow copy of self.
)_maybe_match_namesry   rename)r^   ra  ry   s      r`   rC  &MultiIndex._get_reconciled_name_object  s4     ''.::;;u%%rc   c                8   [        U R                  5      [        UR                  5      :w  a  S/[        U R                  5      -  $ / n[        U R                  UR                  5       H.  u  p4X4:X  a  UR                  U5        M  UR                  S5        M0     U$ )z
Try to find common names to attach to the result of an operation between
a and b. Return a consensus list of names if they match at least partly
or list of None if they have completely different names.
N)r   ry   r   r   )r^   ra  ry   a_nameb_names        r`   rM  MultiIndex._maybe_match_names  sy     tzz?c%++..6C

O++!$**ekk:NFV$ T" ; rc   c                J    U R                  U5      u  p4UR                  U5      $ r   )r?  	set_namesr^   ra  r   r  rF  s        r`   _wrap_intersection_result$MultiIndex._wrap_intersection_result  s%    44U;--rc   c                    U R                  U5      u  p4[        U5      S:X  a  UR                  5       R                  U5      $ UR                  U5      $ r  )r?  r   r5  rU  rV  s        r`   _wrap_difference_result"MultiIndex._wrap_difference_result  sK    44U;v;!..0::<HH##L11rc   c                .   U R                   n[        U[        5      (       dC  [        U5      S:X  a  U S S U R                   4$ Sn [        R                  XR                   S9nX4$ [        X5      nX4$ ! [        [        4 a  n[        U5      UeS nAff = f)Nr   z.other must be a MultiIndex or a list of tuplesr[  )	ry   r   rA   r   rN   r   r   rz   rD   )r^   ra  rF  r  r  s        r`   r?   MultiIndex._convert_can_do_setop  s    zz%''5zQBQx++F2&225

2KE "" /t;L"" #I. 2 $C.c12s   A3 3BBBc                    [        U5      n[        U[        5      (       a  Sn[        U5      e[	        U5      (       d  [        S5      eUSL a  U R                  5       $ U $ )Nz3> 1 ndim Categorical are not supported at this timezISetting a MultiIndex dtype to anything other than object is not supportedT)r3   r   r4   r   r1   rz   r  )r^   r   r   r  s       r`   rs   MultiIndex.astype  sa    U#e-..GC%c**u%%#  4<::<rc   c                4   [        U[        5      (       a1  UR                  U R                  :w  a  [        S5      eUR                  $ [        U[
        5      (       d  U4SU R                  S-
  -  -   nU$ [        U5      U R                  :w  a  [        S5      eU$ )Nz0Item must have length equal to number of levels.)r  rU   )r   rN   r   r   r   r   r   )r^   items     r`   _validate_fill_valueMultiIndex._validate_fill_value)  s    dJ''||t||+ !STT<<D%(( 7UdllQ&677D  Y$,,&OPPrc   c                6   [        X5      u  pU(       a  U R                  5       $ [        U5      [        U5      :X  a  X!   R                  5       nOUR                  5       n/ n/ n[	        [        UR                  U R                  U R                  5      5       Hj  u  nu  pn
U	R                  USS9nUR                  UR                  U5      5      n[        U
5      nXU'   UR                  U5        UR                  U5        Ml     [        XVU R                  SS9$ )z
Return a new MultiIndex of the values set with the mask.

Parameters
----------
mask : array like
value : MultiIndex
    Must either be the same length as self or length one

Returns
-------
MultiIndex
Fr>  rJ  )r;   r   r   r5  r  r   r   r_   r`  r  r  r+   r   rN   ry   )r^   r  r  noopsubsetr  r   r   value_levelr   r   	new_levelvalue_codesnew_codes                 r`   putmaskMultiIndex.putmask7  s     &d1
99;t9E
"[557F//1F
	4=t{{DJJ75
0A0K Ke<I#33F4K4KA4NOK#K0H(TNi(X&5
 djjSX
 	
rc   c                   U R                  U5      n/ n/ n[        X R                  U R                  5       Hy  u  pVnXV;  a  [	        U5      nUR                  X5      nOUR                  U5      nUR                  U5        UR                  [        R
                  " [        U5      X5      5        M{     [        X4U R                  SS9$ )z
Make new MultiIndex inserting new item at location

Parameters
----------
loc : int
item : tuple
    Must be same length as number of levels in the MultiIndex

Returns
-------
new_index : Index
FrJ  )rb  r   r   r_   r   insertrb  r   rZ   r+   rN   ry   )	r^   r~  ra  r  r   r_  r   r   lev_locs	            r`   rn  MultiIndex.insert_  s     ((.
	%({{DJJ%G!Ak~ e*W0--*e$RYY|K'@#OP &H djjSX
 	
rc   c                    U R                    Vs/ s H  n[        R                  " X!5      PM     nn[        U R                  UU R
                  SS9$ s  snf )zU
Make new index with passed location deleted

Returns
-------
new_index : MultiIndex
FrJ  )r_   rZ   r{  rN   r   ry   )r^   r~  r   r   s       r`   r{  MultiIndex.delete  sN     EIJJOJ[RYY{0J	O;;**"	
 	
 Ps    Ac                6   [        U[        5      (       a  [        U5      nUc  [        U5      S:X  a-  [        R
                  " [        U 5      4[        R                  S9$ [        U[        5      (       d  [        R                  U5      nUR                  5       R                  U 5      S:g  $ U R                  U5      nU R                  U5      nUR                  S:X  a,  [        R
                  " [        U5      [        R                  S9$ UR                  U5      $ )Nr   r   r   )r   r   r   r   rZ   r   r  rN   r   r  r  r  r  r  r  )r^   r   r   numlevss        r`   r  MultiIndex.isin  s    fi((&\F=6{axxTBHH==fj11#//7==?2248B>>((/C((-DyyA~xxD	::99V$$rc   __add____radd____iadd____sub____rsub____isub____pow____rpow____mul____rmul____floordiv____rfloordiv____truediv____rtruediv____mod____rmod__
__divmod____rdivmod____neg____pos____abs__
__invert__)r   r  )NNNNNFNT)r   rw  r   rw  rv  r   )r   r   r   r   )NNN)r_   list | Noner   r  r   zlist[int] | range | None)r   r   ry   -Sequence[Hashable] | Hashable | lib.NoDefaultrv  rN   rT  )r   zIterable[tuple[Hashable, ...]]r   r   ry   $Sequence[Hashable] | Hashable | Nonerv  rN   )r   zSequence[Iterable[Hashable]]r   r   ry   r  rv  rN   )r   rL   r   r   ry   r  rv  rN   )rv  
np.ndarray)rv  rM   )rv  r   )rv  rE   )r   rw  r   rw  r   rw  rv  None)r   rw  rv  rN   )rv  r    )rv  zCallable[..., MultiIndex])r   r  rv  rN   )rv  rN   )NFN)rS  rw  rv  r   r   )rv  r   )re  r   rv  rw  )rv  znp.dtyperu  F)rS  rw  rv  r   )r  r  rv  znpt.NDArray[np.object_])NNNF   NT)rx   zbool | Noner  Callable | Noner  z
str | Nonery   rw  r  r   r  rw  rv  r   )r  rw  r  zbool | None | lib.NoDefaultr  r  rv  r   )r   rw  )rv  r  )rv  z	list[str])first)r  r   rv  r  )r   )r  r   rv  rN   )r   r   r  rw  rv  rA   )rv  rA   )r   rw  r  rw  rv  rL   )r(  rw  rv  rN   )r^   rN   rF  r@  rv  rN   )r   TN)r^   rN   rW   r   rO  rw  rv  rN   )rg  r  rv  npt.NDArray[np.intp])rr  r   rv  rN   )Nraise)r   z.Index | np.ndarray | Iterable[Hashable] | Noner|  r   rv  rN   )r  )r|  r   rv  rN   )r  r   )T)r   rw  rv  z!Generator[np.ndarray, None, None])rv  zlist[Categorical])r   TTr  )
r   r   r  zbool | list[bool]r  rw  rg  r  rv  z'tuple[MultiIndex, npt.NDArray[np.intp]])r  rw  )rk  rA   r  rw  rv  rA   )rv  r  )r  r  rv  z"tuple[Index, npt.NDArray[np.intp]])r  r  rv  r  )rv  r  )r  zHashable | Sequence[Hashable]r  Literal['left', 'right']rv  r   )rv  ztuple[int, int])r  )r  r   r  r  )r  rA   re  r   rv  r   )r   T)r   r   r  rw  )r   )r   zint | list[int])r   N)r   r   r  znpt.NDArray[np.bool_] | None)r  z,tuple[Scalar | Iterable | AnyArrayLike, ...]r  r  rv  r  )ra  rr   rv  rw  )ra  rN   rv  rw  )r   r   rv  rw  )r   rN   rv  rN   )r   rw  )r  rN   rv  rN   )r~  r   rv  rN   r  )re   rf   rg   rh   ri   rA   _hidden_attrs	frozenset_typr   __annotations__rE   r  r   _comparablesr   r   r   classmethodr   r   r   r   r   r   r   r'   r   propertyr   r   r   r  r  r   r   r$  r   r-  r_   r   r;  rG  rK  r(   rN  r  r   r\  r5  rf  r   ry  r~  r  r}  r  r  r  r  r  r   ry   r  r  r  r  rx  r   _duplicatedr  r	  r  r  r  r  r  r!  r   r*  r5  r;  rC  rG  r&   rB   _index_doc_kwargsr  r   r&  rn  r  rv  r  r  r  r  rj  r  r  r  r  r  r  r  r  r  r  r  r  rb  r  r  r  r  r  r,  r2  r;  rA  rJ  rC  rM  rW  rZ  r?  rs   rb  rk  rn  r{  r  rU  rN  rF   rw  rx  ry  rz  r{  r|  r}  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rm   __classcell__)r  s   @r`   rN   rN      s.
   Qf '')+5M D$&F!&lG\F9L !%- - - 
-^4 ""59	LL L 3	L\  !%?B~~	D
 D
 =	D

 
D
 D
L  !%6:	MI.MI MI 4	MI
 
MI  MI^  !%?B~~	:D/:D :D =	:D
 
:D :Dx  !%6:	BJBJ BJ 4	BJ
 
BJ BJL  2   
 
 R R4"   8" 8"| !&+
 + + + 
+\  $d`7;`	`D ! ! 2 2$   !&'
 ' ' ' 
'T #T>6:>	>F F F: & & 			58^^ K K

" 	> >
 
>@ 			   E 			" " # #2K  %""	 "L !%)!O!O! #O! 	O!
 O! O! O! 
O!l &*= = .	=
 #= 
=D' *. 8t E*  6 ? ?< 2 2 6 6 			% % KH 	
/ 
/442h 	D D ^^!&	XX 	X
 
Xx8<"3H 8 8A
FSp7 D
$  (+<<= 

 
 	
 

 >
>=%@ )/P"%P	P  *->>?
 @
( AE%	Y! >Y! 	Y!
 
Y!x 3:$/	*8
t"H
 (, $	*
, '+#"c"c" %c" 	c"
 c" 
1c"J ) = =;!;	+;F(*29,29 '29 
	29j54 54n1Kf,2xXt5nS)l LPo%o%,Ho%bC7NV9V &V 
	Vp+
Z<|  D&
".2#* 	 &
P!
F
  	_% %( __F
 i(Gz*Hz*Hi(Gz*Hz*Hi(Gz*Hi(Gz*H">2L#O4M!-0K">2Li(Gz*H .J!-0Ki(Gi(Gi(G .Jrc   c                    U  Vs/ s H  n[        U5      PM     nn[        USS5       H%  n[        R                  " USU 5      (       d  M#  Us  $    gs  snf )zJCount depth (up to a maximum of `nlevels`) with which codes are lexsorted.r   r   N)r+   r   r  r  )r_   r   r   int64_codesr_  s        r`   r   r     sU    @EF<,KF7Ar"  Ra11H # 	 Gs   Ac                   [        [        U 6 5      n[        U 5      nUS US-    nX1   nX1S-   S   H  n/ n[        [        Xg5      5       Hp  u  n	u  pXS-
  :X  a$  UR	                  U5        UR	                  U5          O@X:X  a  UR	                  U5        ML  UR                  XyS  5        UR	                  U5          O   UnM     [        [        U6 5      $ )NrU   )r   r   r   r  r   r  )
label_listr  r  pivotedr_  r   prevcur
sparse_curr   pts               r`   r  r    s    3
#$GJA[uqy!F>Dqy{#
"3t>2IAvEz!!!$ j)v!!(+!!#b'* j) 3" ) $, Vrc   c                    [        U [        5      (       a  U R                   $ U R                  n[        R
                  S[        R                  S0R                  US5      $ )NNaTNaN)r   r5   rP  rJ  rZ   
datetime64timedelta64get)r   
dtype_types     r`   r  r    sI    %((..!"ZZ
MM5"..%8<<ZOOrc   c                    U n[        U[        5      (       a  U H  n U R                  S/5      n M     U $  U R                  S/5      n U $ ! [         a    Us s  $ f = f! [         a     U $ f = f)z
Attempt to drop level or levels from the given index.

Parameters
----------
index: Index
key : scalar or tuple

Returns
-------
Index
r   )r   r   r  r   )r   re  original_indexr  s       r`   maybe_droplevelsr    s     N#u A&111#6  L	--qc2E L  &%%&  	L	s"   AA AA
A-,A-c                l    [        X5      n U(       a  U R                  5       n SU R                  l        U $ )z
Coerce the array-like indexer to the smallest integer dtype that can encode all
of the given categories.

Parameters
----------
array_like : array-like
categories : array-like
copy : bool

Returns
-------
np.ndarray
    Non-writeable.
F)r*   r   r  r  )
array_liker  r   s      r`   r4  r4    s1      &j=J__&
!&Jrc   c                d   U bg  [        U 5      (       dW  [        U5      (       d  [        U S35      e[        U5      S:  a!  [        US   5      (       a  [        U S35      eU /n U/nX4$ U b  [        U 5      (       a1  [        U5      (       a  [        US   5      (       d  [        U S35      eX4$ )zL
Ensure that level is either None or listlike, and arr is list-of-listlike.
z must be list-liker   z must be list of lists-like)r0   rz   r   )r   r   arrnames      r`   r"  r"  /  s     e!4!4C  wi'9:;;s8a<LQ00wi'9:;;e : 
,u--C  SV(<(<wi'BCDD:rc   )r   r   rv  r   )r_   zlist[np.ndarray]r   r   rv  r   )r   r  )r  r   r  rr   )r   r   rv  r  )r   rA   rv  rA   r  )r   rw  rv  r  )r  r  )
__future__r   collections.abcr   r   r   r   r   	functoolsr	   sysr   typingr   r   r   r   r   r  numpyrZ   pandas._configr   pandas._libsr   r  r   rj   r   pandas._libs.hashtabler   pandas._typingr   r   r   r   r   r   r   r   r   r   r    r!   pandas.compat.numpyr"   rK  pandas.errorsr#   r$   r%   pandas.util._decoratorsr&   r'   r(   pandas.util._exceptionsr)   pandas.core.dtypes.castr*   pandas.core.dtypes.commonr+   r,   r-   r.   r/   r0   r1   r2   r3   pandas.core.dtypes.dtypesr4   r5   pandas.core.dtypes.genericr6   r7   pandas.core.dtypes.inferencer8   pandas.core.dtypes.missingr9   r:   pandas.core.algorithmscore
algorithmspandas.core.array_algos.putmaskr;   pandas.core.arraysr<   r=   pandas.core.arrays.categoricalr>   r?   pandas.core.commoncommonr   pandas.core.constructionr@   pandas.core.indexes.baseindexesbaser8  rA   rB   rC   rD   pandas.core.indexes.frozenrE   pandas.core.ops.invalidrF   pandas.core.sortingrG   rH   pandas.io.formats.printingrI   rJ   r   rK   rL   rM   dictr  updateBaseMultiIndexCodesEnginerk   rR   ru   ro   r   rN   r   r  r  r  r4  r"  rd   rc   r`   <module>r     s}   "       % 
 .    / 
 
 5 8
 
 
 7
 ' & < !   3 ( (  2 3

   001    ,JK
$38==x?T?T $3N&3H>>@U@U &3R&_;/ _;/Dw@PB.rc   