@@ -896,8 +896,11 @@ def _multi_take(self, tup):
896
896
d = {}
897
897
for key , axis in zip (tup , o ._AXIS_ORDERS ):
898
898
ax = o ._get_axis (axis )
899
+ # Have the index compute an indexer or return None
900
+ # if it cannot handle:
899
901
indexer , keyarr = ax ._convert_listlike_indexer (key ,
900
902
kind = self .name )
903
+ # We only act on all found values:
901
904
if indexer is not None and (indexer != - 1 ).all ():
902
905
self ._validate_read_indexer (key , indexer , axis )
903
906
d [axis ] = (ax [indexer ], indexer )
@@ -1146,39 +1149,58 @@ def _getitem_iterable(self, key, axis=None):
1146
1149
1147
1150
def _validate_read_indexer (self , key , indexer , axis ):
1148
1151
"""
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.
1151
1172
"""
1173
+
1152
1174
ax = self .obj ._get_axis (axis )
1153
- # True indicates missing values
1175
+
1154
1176
if len (key ) == 0 :
1155
1177
return
1156
1178
1157
- missing = indexer < 0
1179
+ # Count missing values:
1180
+ missing = (indexer < 0 ).sum ()
1158
1181
1159
- if np . any ( missing ) :
1160
- if np . all ( missing ):
1182
+ if missing :
1183
+ if missing == len ( indexer ):
1161
1184
raise KeyError (
1162
1185
u"None of [{key}] are in the [{axis}]" .format (
1163
1186
key = key , axis = self .obj ._get_axis_name (axis )))
1164
- else :
1165
1187
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
1171
1193
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.
1175
1197
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
1178
1200
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 )
1182
1204
1183
1205
def _convert_to_indexer (self , obj , axis = None , is_setter = False ):
1184
1206
"""
@@ -1371,29 +1393,45 @@ def _validate_key(self, key, axis):
1371
1393
return True
1372
1394
1373
1395
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
+
1374
1412
if axis is None :
1375
1413
axis = self .axis or 0
1376
1414
labels = self .obj ._get_axis (axis )
1377
1415
1378
1416
if com .is_bool_indexer (key ):
1379
1417
key = check_bool_indexer (labels , key )
1380
1418
return labels [key ]
1419
+
1420
+ if isinstance (key , Index ):
1421
+ keyarr = labels ._convert_index_indexer (key )
1381
1422
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 )
1397
1435
1398
1436
return keyarr
1399
1437
0 commit comments