@@ -2591,7 +2591,7 @@ def _partial_tup_index(self, tup, side="left"):
25912591 for k , (lab , lev , labs ) in enumerate (zipped ):
25922592 section = labs [start :end ]
25932593
2594- if lab not in lev :
2594+ if lab not in lev and not isna ( lab ) :
25952595 if not lev .is_type_compatible (lib .infer_dtype ([lab ], skipna = False )):
25962596 raise TypeError ("Level type mismatch: %s" % lab )
25972597
@@ -2601,13 +2601,45 @@ def _partial_tup_index(self, tup, side="left"):
26012601 loc -= 1
26022602 return start + section .searchsorted (loc , side = side )
26032603
2604- idx = lev . get_loc ( lab )
2604+ idx = self . _get_loc_single_level_index_wrapper ( lev , lab )
26052605 if k < n - 1 :
26062606 end = start + section .searchsorted (idx , side = "right" )
26072607 start = start + section .searchsorted (idx , side = "left" )
26082608 else :
26092609 return start + section .searchsorted (idx , side = side )
26102610
2611+ def _get_loc_single_level_index_wrapper (self , level_index : Index , key ) -> int :
2612+ """
2613+ Wrapper function for MultiIndex.
2614+ If key is NA value, location of index unify as -1.
2615+
2616+ Parameters
2617+ ----------
2618+ level_index: Index
2619+ Single level index in MultiIndex
2620+ key : label
2621+
2622+ Returns
2623+ -------
2624+ loc : int
2625+ If key is NA value, loc is -1
2626+ Else, location of key in index
2627+
2628+ See Also
2629+ --------
2630+ Index.get_loc : The get_loc method for (single-level) index.
2631+
2632+ Notes
2633+ -----
2634+ Depending on Index type, Handling NA value is different using get_loc.
2635+ But in MultiIndex, NA values is denoted as missing by -1.
2636+ """
2637+
2638+ if is_scalar (key ) and isna (key ):
2639+ return - 1
2640+ else :
2641+ return level_index .get_loc (key )
2642+
26112643 def get_loc (self , key , method = None ):
26122644 """
26132645 Get location for a label or a tuple of labels as an integer, slice or
@@ -2707,7 +2739,9 @@ def _maybe_to_slice(loc):
27072739 loc = np .arange (start , stop , dtype = "int64" )
27082740
27092741 for i , k in enumerate (follow_key , len (lead_key )):
2710- mask = self .codes [i ][loc ] == self .levels [i ].get_loc (k )
2742+ mask = self .codes [i ][loc ] == self ._get_loc_single_level_index_wrapper (
2743+ self .levels [i ], k
2744+ )
27112745 if not mask .all ():
27122746 loc = loc [mask ]
27132747 if not len (loc ):
@@ -2934,8 +2968,7 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
29342968 return slice (i , j , step )
29352969
29362970 else :
2937-
2938- code = level_index .get_loc (key )
2971+ code = self ._get_loc_single_level_index_wrapper (level_index , key )
29392972
29402973 if level > 0 or self .lexsort_depth == 0 :
29412974 # Desired level is not sorted
0 commit comments