Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion xarray/core/indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import numpy as np
import pandas as pd
from pandas.errors import InvalidIndexError

from xarray.core import formatting, nputils, utils
from xarray.core.coordinate_transform import CoordinateTransform
Expand Down Expand Up @@ -1367,7 +1368,14 @@ def sel(self, labels, method=None, tolerance=None) -> IndexSelResult:

elif isinstance(label, tuple):
if _is_nested_tuple(label):
indexer = self.index.get_locs(label)
# When the tuple contains sub-tuples/lists/slices, it could be:
# 1. A single key with tuple-valued levels (e.g., ((1, 1), 2))
# 2. A multi-value selection (e.g., (1, slice(1, 2)))
# Try get_loc first for case 1, fall back to get_locs for case 2
try:
indexer = self.index.get_loc(label)
except (InvalidIndexError, KeyError):
indexer = self.index.get_locs(label)
elif len(label) == self.index.nlevels:
indexer = self.index.get_loc(label)
else:
Expand Down
16 changes: 16 additions & 0 deletions xarray/tests/test_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,22 @@ def test_copy(self) -> None:
assert actual.dim == expected.dim
assert actual.level_coords_dtype == expected.level_coords_dtype

def test_sel_nested_tuple_key_collapses_dimension(self) -> None:
# Regression test for GH#11341
# When indexing with a single nested tuple key (where one level has
# tuple-valued entries), the dimension should collapse like scalar selection
nested_level_0 = pd.Index(
[(1, 1), (1, 1), (2, 2), (3, 3)], name="a", tupleize_cols=False
)
nested_level_1 = pd.Index([1, 2, 10, 20], name="b")
nested_mi = pd.MultiIndex.from_arrays([nested_level_0, nested_level_1])
index = PandasMultiIndex(nested_mi, "index")

# A single nested tuple key should produce a scalar indexer (int),
# not an array, collapsing the dimension
actual = index.sel({"index": ((1, 1), 2)})
assert isinstance(actual.dim_indexers["index"], (int, np.integer))


class TestIndexes:
@pytest.fixture
Expand Down
Loading