@@ -897,8 +897,11 @@ def _multi_take(self, tup):
897
897
d = {}
898
898
for key , axis in zip (tup , o ._AXIS_ORDERS ):
899
899
ax = o ._get_axis (axis )
900
+ # Have the index compute an indexer or return None
901
+ # if it cannot handle:
900
902
indexer , keyarr = ax ._convert_listlike_indexer (key ,
901
903
kind = self .name )
904
+ # We only act on all found values:
902
905
if indexer is not None and (indexer != - 1 ).all ():
903
906
self ._validate_read_indexer (key , indexer , axis )
904
907
d [axis ] = (ax [indexer ], indexer )
@@ -1147,39 +1150,58 @@ def _getitem_iterable(self, key, axis=None):
1147
1150
1148
1151
def _validate_read_indexer (self , key , indexer , axis ):
1149
1152
"""
1150
- Check that indexer is OK (e.g. at least one element was found, unless
1151
- the list of keys was actually empty).
1153
+ Check that indexer can be used to return a result (e.g. at least one
1154
+ element was found, unless the list of keys was actually empty).
1155
+
1156
+ Parameters
1157
+ ----------
1158
+ key : list-like
1159
+ Target labels (only used to show correct error message)
1160
+ indexer: array-like of booleans
1161
+ Indices corresponding to the key (with -1 indicating not found)
1162
+ axis: int
1163
+ Dimension on which the indexing is being made
1164
+
1165
+ Returns
1166
+ -------
1167
+ None
1168
+
1169
+ Raises
1170
+ ------
1171
+ KeyError
1172
+ If at least one key was requested none was found.
1152
1173
"""
1174
+
1153
1175
ax = self .obj ._get_axis (axis )
1154
- # True indicates missing values
1176
+
1155
1177
if len (key ) == 0 :
1156
1178
return
1157
1179
1158
- missing = indexer < 0
1180
+ # Count missing values:
1181
+ missing = (indexer < 0 ).sum ()
1159
1182
1160
- if np . any ( missing ) :
1161
- if np . all ( missing ):
1183
+ if missing :
1184
+ if missing == len ( indexer ):
1162
1185
raise KeyError (
1163
1186
u"None of [{key}] are in the [{axis}]" .format (
1164
1187
key = key , axis = self .obj ._get_axis_name (axis )))
1165
- else :
1166
1188
1167
- # we skip the warning on Categorical/Interval
1168
- # as this check is actually done (check for
1169
- # non-missing values), but a bit later in the
1170
- # code, so we want to avoid warning & then
1171
- # just raising
1189
+ # we skip the warning on Categorical/Interval
1190
+ # as this check is actually done (check for
1191
+ # non-missing values), but a bit later in the
1192
+ # code, so we want to avoid warning & then
1193
+ # just raising
1172
1194
1173
- _missing_key_warning = textwrap .dedent ("""
1174
- Passing list-likes to .loc or [] with any missing label will raise
1175
- KeyError in the future, you can use .reindex() as an alternative.
1195
+ _missing_key_warning = textwrap .dedent ("""
1196
+ Passing list-likes to .loc or [] with any missing label will raise
1197
+ KeyError in the future, you can use .reindex() as an alternative.
1176
1198
1177
- See the documentation here:
1178
- https://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike""" ) # noqa
1199
+ See the documentation here:
1200
+ https://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike""" ) # noqa
1179
1201
1180
- if not (ax .is_categorical () or ax .is_interval ()):
1181
- warnings .warn (_missing_key_warning ,
1182
- FutureWarning , stacklevel = 5 )
1202
+ if not (ax .is_categorical () or ax .is_interval ()):
1203
+ warnings .warn (_missing_key_warning ,
1204
+ FutureWarning , stacklevel = 5 )
1183
1205
1184
1206
def _convert_to_indexer (self , obj , axis = None , is_setter = False ):
1185
1207
"""
@@ -1372,31 +1394,47 @@ def _validate_key(self, key, axis):
1372
1394
return True
1373
1395
1374
1396
def _convert_for_reindex (self , key , axis = None ):
1397
+ """
1398
+ Transform a list of keys into a new array ready to be used as axis of
1399
+ the object we return (e.g. including NaNs).
1400
+
1401
+ Parameters
1402
+ ----------
1403
+ key : list-like
1404
+ Target labels
1405
+ axis: int
1406
+ Where the indexing is being made
1407
+
1408
+ Returns
1409
+ -------
1410
+ list-like of labels
1411
+ """
1412
+
1375
1413
if axis is None :
1376
1414
axis = self .axis or 0
1377
1415
labels = self .obj ._get_axis (axis )
1378
1416
1379
1417
if com .is_bool_indexer (key ):
1380
1418
key = check_bool_indexer (labels , key )
1381
1419
return labels [key ]
1420
+
1421
+ if isinstance (key , Index ):
1422
+ keyarr = labels ._convert_index_indexer (key )
1382
1423
else :
1383
- if isinstance (key , Index ):
1384
- keyarr = labels ._convert_index_indexer (key )
1385
- else :
1386
- # asarray can be unsafe, NumPy strings are weird
1387
- keyarr = com ._asarray_tuplesafe (key )
1424
+ # asarray can be unsafe, NumPy strings are weird
1425
+ keyarr = com ._asarray_tuplesafe (key )
1388
1426
1389
- if is_integer_dtype (keyarr ):
1390
- # Cast the indexer to uint64 if possible so
1391
- # that the values returned from indexing are
1392
- # also uint64.
1393
- keyarr = labels ._convert_arr_indexer (keyarr )
1427
+ if is_integer_dtype (keyarr ):
1428
+ # Cast the indexer to uint64 if possible so
1429
+ # that the values returned from indexing are
1430
+ # also uint64.
1431
+ keyarr = labels ._convert_arr_indexer (keyarr )
1394
1432
1395
- if not labels .is_integer ():
1396
- keyarr = _ensure_platform_int (keyarr )
1397
- return labels .take (keyarr )
1433
+ if not labels .is_integer ():
1434
+ keyarr = _ensure_platform_int (keyarr )
1435
+ return labels .take (keyarr )
1398
1436
1399
- return keyarr
1437
+ return keyarr
1400
1438
1401
1439
1402
1440
class _LocationIndexer (_NDFrameIndexer ):
0 commit comments