@@ -896,8 +896,11 @@ def _multi_take(self, tup):
896896 d = {}
897897 for key , axis in zip (tup , o ._AXIS_ORDERS ):
898898 ax = o ._get_axis (axis )
899+ # Have the index compute an indexer or return None
900+ # if it cannot handle:
899901 indexer , keyarr = ax ._convert_listlike_indexer (key ,
900902 kind = self .name )
903+ # We only act on all found values:
901904 if indexer is not None and (indexer != - 1 ).all ():
902905 self ._validate_read_indexer (key , indexer , axis )
903906 d [axis ] = (ax [indexer ], indexer )
@@ -1146,39 +1149,58 @@ def _getitem_iterable(self, key, axis=None):
11461149
11471150 def _validate_read_indexer (self , key , indexer , axis ):
11481151 """
1149- Check that indexer is OK (e.g. at least one element was found, unless
1150- the list of keys was actually empty).
1152+ Check that indexer can be used to return a result (e.g. at least one
1153+ element was found, unless the list of keys was actually empty).
1154+
1155+ Parameters
1156+ ----------
1157+ key : list-like
1158+ Target labels (only used to show correct error message)
1159+ indexer: array-like of booleans
1160+ Indices corresponding to the key (with -1 indicating not found)
1161+ axis: int
1162+ Dimension on which the indexing is being made
1163+
1164+ Returns
1165+ -------
1166+ None
1167+
1168+ Raises
1169+ ------
1170+ KeyError
1171+ If at least one key was requested none was found.
11511172 """
1173+
11521174 ax = self .obj ._get_axis (axis )
1153- # True indicates missing values
1175+
11541176 if len (key ) == 0 :
11551177 return
11561178
1157- missing = indexer < 0
1179+ # Count missing values:
1180+ missing = (indexer < 0 ).sum ()
11581181
1159- if np . any ( missing ) :
1160- if np . all ( missing ):
1182+ if missing :
1183+ if missing == len ( indexer ):
11611184 raise KeyError (
11621185 u"None of [{key}] are in the [{axis}]" .format (
11631186 key = key , axis = self .obj ._get_axis_name (axis )))
1164- else :
11651187
1166- # we skip the warning on Categorical/Interval
1167- # as this check is actually done (check for
1168- # non-missing values), but a bit later in the
1169- # code, so we want to avoid warning & then
1170- # just raising
1188+ # we skip the warning on Categorical/Interval
1189+ # as this check is actually done (check for
1190+ # non-missing values), but a bit later in the
1191+ # code, so we want to avoid warning & then
1192+ # just raising
11711193
1172- _missing_key_warning = textwrap .dedent ("""
1173- Passing list-likes to .loc or [] with any missing label will raise
1174- KeyError in the future, you can use .reindex() as an alternative.
1194+ _missing_key_warning = textwrap .dedent ("""
1195+ Passing list-likes to .loc or [] with any missing label will raise
1196+ KeyError in the future, you can use .reindex() as an alternative.
11751197
1176- See the documentation here:
1177- https://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike""" ) # noqa
1198+ See the documentation here:
1199+ https://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike""" ) # noqa
11781200
1179- if not (ax .is_categorical () or ax .is_interval ()):
1180- warnings .warn (_missing_key_warning ,
1181- FutureWarning , stacklevel = 5 )
1201+ if not (ax .is_categorical () or ax .is_interval ()):
1202+ warnings .warn (_missing_key_warning ,
1203+ FutureWarning , stacklevel = 5 )
11821204
11831205 def _convert_to_indexer (self , obj , axis = None , is_setter = False ):
11841206 """
@@ -1371,29 +1393,45 @@ def _validate_key(self, key, axis):
13711393 return True
13721394
13731395 def _convert_for_reindex (self , key , axis = None ):
1396+ """
1397+ Transform a list of keys into a new array ready to be used as axis of
1398+ the object we return (e.g. including NaNs).
1399+
1400+ Parameters
1401+ ----------
1402+ key : list-like
1403+ Target labels
1404+ axis: int
1405+ Where the indexing is being made
1406+
1407+ Returns
1408+ -------
1409+ list-like of labels
1410+ """
1411+
13741412 if axis is None :
13751413 axis = self .axis or 0
13761414 labels = self .obj ._get_axis (axis )
13771415
13781416 if com .is_bool_indexer (key ):
13791417 key = check_bool_indexer (labels , key )
13801418 return labels [key ]
1419+
1420+ if isinstance (key , Index ):
1421+ keyarr = labels ._convert_index_indexer (key )
13811422 else :
1382- if isinstance (key , Index ):
1383- keyarr = labels ._convert_index_indexer (key )
1384- else :
1385- # asarray can be unsafe, NumPy strings are weird
1386- keyarr = com ._asarray_tuplesafe (key )
1387-
1388- if is_integer_dtype (keyarr ):
1389- # Cast the indexer to uint64 if possible so
1390- # that the values returned from indexing are
1391- # also uint64.
1392- keyarr = labels ._convert_arr_indexer (keyarr )
1393-
1394- if not labels .is_integer ():
1395- keyarr = _ensure_platform_int (keyarr )
1396- return labels .take (keyarr )
1423+ # asarray can be unsafe, NumPy strings are weird
1424+ keyarr = com ._asarray_tuplesafe (key )
1425+
1426+ if is_integer_dtype (keyarr ):
1427+ # Cast the indexer to uint64 if possible so
1428+ # that the values returned from indexing are
1429+ # also uint64.
1430+ keyarr = labels ._convert_arr_indexer (keyarr )
1431+
1432+ if not labels .is_integer ():
1433+ keyarr = _ensure_platform_int (keyarr )
1434+ return labels .take (keyarr )
13971435
13981436 return keyarr
13991437
0 commit comments