Skip to content

Commit

Permalink
REGR: Series access with Index of tuples/frozenset (pandas-dev#36147)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhshadrach authored and Kevin D Smith committed Nov 2, 2020
1 parent c8392b7 commit bcbac92
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
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 @@ -889,21 +889,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 @@ -963,7 +961,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,9 +1015,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

0 comments on commit bcbac92

Please sign in to comment.