Skip to content

Backport PR #36147 on branch 1.1.x (REGR: Series access with Index of tuples/frozenset) #36332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v1.1.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ including other versions of pandas.

Fixed regressions
~~~~~~~~~~~~~~~~~
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a tuple (:issue:`35534`)
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a frozenset (:issue:`35747`)
-

.. ---------------------------------------------------------------------------
Expand Down
22 changes: 11 additions & 11 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,21 +881,19 @@ def __getitem__(self, key):
elif key_is_scalar:
return self._get_value(key)

if (
isinstance(key, tuple)
and is_hashable(key)
and isinstance(self.index, MultiIndex)
):
if is_hashable(key):
# Otherwise index.get_value will raise InvalidIndexError
try:
# For labels that don't resolve as scalars like tuples and frozensets
result = self._get_value(key)

return result

except KeyError:
# We still have the corner case where this tuple is a key
# in the first level of our MultiIndex
return self._get_values_tuple(key)
if isinstance(key, tuple) and isinstance(self.index, MultiIndex):
# We still have the corner case where a tuple is a key
# in the first level of our MultiIndex
return self._get_values_tuple(key)

if is_iterator(key):
key = list(key)
Expand Down Expand Up @@ -955,7 +953,7 @@ def _get_values_tuple(self, key):
return result

if not isinstance(self.index, MultiIndex):
raise ValueError("Can only tuple-index with a MultiIndex")
raise ValueError("key of type tuple not found and not a MultiIndex")

# If key is contained, would have returned by now
indexer, new_index = self.index.get_loc_level(key)
Expand Down Expand Up @@ -1009,9 +1007,11 @@ def __setitem__(self, key, value):
# GH#12862 adding an new key to the Series
self.loc[key] = value

except TypeError as e:
except TypeError as err:
if isinstance(key, tuple) and not isinstance(self.index, MultiIndex):
raise ValueError("Can only tuple-index with a MultiIndex") from e
raise ValueError(
"key of type tuple not found and not a MultiIndex"
) from err

if com.is_bool_indexer(key):
key = check_bool_indexer(self.index, key)
Expand Down
21 changes: 20 additions & 1 deletion pandas/tests/series/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def test_2d_to_1d_assignment_raises():
@pytest.mark.filterwarnings("ignore:Using a non-tuple:FutureWarning")
def test_basic_getitem_setitem_corner(datetime_series):
# invalid tuples, e.g. td.ts[:, None] vs. td.ts[:, 2]
msg = "Can only tuple-index with a MultiIndex"
msg = "key of type tuple not found and not a MultiIndex"
with pytest.raises(ValueError, match=msg):
datetime_series[:, 2]
with pytest.raises(ValueError, match=msg):
Expand Down Expand Up @@ -942,3 +942,22 @@ def assert_slices_equivalent(l_slc, i_slc):
for key2 in [keystr2, box(keystr2)]:
assert_slices_equivalent(SLC[key2:key:-1], SLC[13:8:-1])
assert_slices_equivalent(SLC[key:key2:-1], SLC[0:0:-1])


def test_tuple_index():
# GH 35534 - Selecting values when a Series has an Index of tuples
s = pd.Series([1, 2], index=[("a",), ("b",)])
assert s[("a",)] == 1
assert s[("b",)] == 2
s[("b",)] = 3
assert s[("b",)] == 3


def test_frozenset_index():
# GH35747 - Selecting values when a Series has an Index of frozenset
idx0, idx1 = frozenset("a"), frozenset("b")
s = pd.Series([1, 2], index=[idx0, idx1])
assert s[idx0] == 1
assert s[idx1] == 2
s[idx1] = 3
assert s[idx1] == 3