| 1289 | return index_vars |
| 1290 | |
| 1291 | def sel(self, labels, method=None, tolerance=None) -> IndexSelResult: |
| 1292 | from xarray.core.dataarray import DataArray |
| 1293 | from xarray.core.variable import Variable |
| 1294 | |
| 1295 | if method is not None or tolerance is not None: |
| 1296 | raise ValueError( |
| 1297 | "multi-index does not support ``method`` and ``tolerance``" |
| 1298 | ) |
| 1299 | |
| 1300 | new_index = None |
| 1301 | scalar_coord_values = {} |
| 1302 | |
| 1303 | indexer: int | slice | np.ndarray | Variable | DataArray |
| 1304 | |
| 1305 | # label(s) given for multi-index level(s) |
| 1306 | if all(lbl in self.index.names for lbl in labels): |
| 1307 | label_values = {} |
| 1308 | for k, v in labels.items(): |
| 1309 | label_array = normalize_label(v, dtype=self.level_coords_dtype[k]) |
| 1310 | try: |
| 1311 | label_values[k] = as_scalar(label_array) |
| 1312 | except ValueError as err: |
| 1313 | # label should be an item not an array-like |
| 1314 | raise ValueError( |
| 1315 | "Vectorized selection is not " |
| 1316 | f"available along coordinate {k!r} (multi-index level)" |
| 1317 | ) from err |
| 1318 | |
| 1319 | has_slice = any(isinstance(v, slice) for v in label_values.values()) |
| 1320 | |
| 1321 | if has_slice: |
| 1322 | slice_levels = [ |
| 1323 | k for k, v in label_values.items() if isinstance(v, slice) |
| 1324 | ] |
| 1325 | raise ValueError( |
| 1326 | f"slice-based selection on multi-index level(s) {slice_levels} " |
| 1327 | f"is not supported. Use scalar values for multi-index level " |
| 1328 | f"selection instead, e.g., ``.sel({slice_levels[0]}=value)``." |
| 1329 | ) |
| 1330 | |
| 1331 | if len(label_values) == self.index.nlevels and not has_slice: |
| 1332 | indexer = self.index.get_loc( |
| 1333 | tuple(label_values[k] for k in self.index.names) |
| 1334 | ) |
| 1335 | else: |
| 1336 | indexer, new_index = self.index.get_loc_level( |
| 1337 | tuple(label_values.values()), level=tuple(label_values.keys()) |
| 1338 | ) |
| 1339 | scalar_coord_values.update(label_values) |
| 1340 | # GH2619. Raise a KeyError if nothing is chosen |
| 1341 | if indexer.dtype.kind == "b" and indexer.sum() == 0: # type: ignore[union-attr] |
| 1342 | raise KeyError(f"{labels} not found") |
| 1343 | |
| 1344 | # assume one label value given for the multi-index "array" (dimension) |
| 1345 | else: |
| 1346 | if len(labels) > 1: |
| 1347 | coord_name = next(iter(set(labels) - set(self.index.names))) |
| 1348 | raise ValueError( |