@@ -2591,7 +2591,7 @@ def _partial_tup_index(self, tup, side="left"):
2591
2591
for k , (lab , lev , labs ) in enumerate (zipped ):
2592
2592
section = labs [start :end ]
2593
2593
2594
- if lab not in lev :
2594
+ if lab not in lev and not isna ( lab ) :
2595
2595
if not lev .is_type_compatible (lib .infer_dtype ([lab ], skipna = False )):
2596
2596
raise TypeError ("Level type mismatch: %s" % lab )
2597
2597
@@ -2601,13 +2601,25 @@ def _partial_tup_index(self, tup, side="left"):
2601
2601
loc -= 1
2602
2602
return start + section .searchsorted (loc , side = side )
2603
2603
2604
- idx = lev . get_loc ( lab )
2604
+ idx = self . _get_loc_single_index_wrapper ( lev , lab )
2605
2605
if k < n - 1 :
2606
2606
end = start + section .searchsorted (idx , side = "right" )
2607
2607
start = start + section .searchsorted (idx , side = "left" )
2608
2608
else :
2609
2609
return start + section .searchsorted (idx , side = side )
2610
2610
2611
+ def _get_loc_single_index_wrapper (self , level_index , key ):
2612
+ """
2613
+ single index get_loc wrapper function for multi index.
2614
+ Depending on index type, Handling NA value is different using get_loc.
2615
+ But in multi index, NA values is denoted as missing by -1.
2616
+ If key is NA value, location of index unify as -1.
2617
+ """
2618
+ if not is_list_like (key ) and isna (key ):
2619
+ return - 1
2620
+ else :
2621
+ return level_index .get_loc (key )
2622
+
2611
2623
def get_loc (self , key , method = None ):
2612
2624
"""
2613
2625
Get location for a label or a tuple of labels as an integer, slice or
@@ -2707,7 +2719,9 @@ def _maybe_to_slice(loc):
2707
2719
loc = np .arange (start , stop , dtype = "int64" )
2708
2720
2709
2721
for i , k in enumerate (follow_key , len (lead_key )):
2710
- mask = self .codes [i ][loc ] == self .levels [i ].get_loc (k )
2722
+ mask = self .codes [i ][loc ] == self ._get_loc_single_index_wrapper (
2723
+ self .levels [i ], k
2724
+ )
2711
2725
if not mask .all ():
2712
2726
loc = loc [mask ]
2713
2727
if not len (loc ):
@@ -2934,8 +2948,7 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
2934
2948
return slice (i , j , step )
2935
2949
2936
2950
else :
2937
-
2938
- code = level_index .get_loc (key )
2951
+ code = self ._get_loc_single_index_wrapper (level_index , key )
2939
2952
2940
2953
if level > 0 or self .lexsort_depth == 0 :
2941
2954
# Desired level is not sorted
0 commit comments