Skip to content
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

REGR: Series access with Index of tuples/frozenset #36147

Merged
merged 12 commits into from
Sep 12, 2020
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v1.1.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Fixed regressions
- Regression in :meth:`DataFrame.replace` where a ``TypeError`` would be raised when attempting to replace elements of type :class:`Interval` (:issue:`35931`)
- Fix regression in pickle roundtrip of the ``closed`` attribute of :class:`IntervalIndex` (:issue:`35658`)
- Fixed regression in :meth:`DataFrameGroupBy.agg` where a ``ValueError: buffer source array is read-only`` would be raised when the underlying array is read-only (:issue:`36014`)
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a tuple. (:issue:`35534`)
rhshadrach marked this conversation as resolved.
Show resolved Hide resolved
rhshadrach marked this conversation as resolved.
Show resolved Hide resolved
- Fixed regression in :meth:`Series.__getitem__` incorrectly raising when the input was a frozenset. (:issue:`35747`)
- Fixed regression in :meth:`Series.groupby.rolling` number of levels of :class:`MultiIndex` in input was compressed to one (:issue:`36018`)
- Fixed regression in :class:`DataFrameGroupBy` on an empty :class:`DataFrame` (:issue:`36197`)

Expand Down
19 changes: 9 additions & 10 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,21 +887,18 @@ 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
rhshadrach marked this conversation as resolved.
Show resolved Hide resolved
try:
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)
rhshadrach marked this conversation as resolved.
Show resolved Hide resolved

if is_iterator(key):
key = list(key)
Expand Down Expand Up @@ -961,7 +958,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 @@ -1017,7 +1014,9 @@ def __setitem__(self, key, value):

except TypeError as e:
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 e
rhshadrach marked this conversation as resolved.
Show resolved Hide resolved

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