Skip to content

Commit f7b2395

Browse files
committed
[BUG] fix .at for multiindexed series
Addresses: GH26989
1 parent 30724b9 commit f7b2395

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

doc/source/whatsnew/v1.1.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ Indexing
360360
- Bug in :class:`Index` constructor where an unhelpful error message was raised for ``numpy`` scalars (:issue:`33017`)
361361
- Bug in :meth:`DataFrame.lookup` incorrectly raising an ``AttributeError`` when ``frame.index`` or ``frame.columns`` is not unique; this will now raise a ``ValueError`` with a helpful error message (:issue:`33041`)
362362
- Bug in :meth:`DataFrame.iloc.__setitem__` creating a new array instead of overwriting ``Categorical`` values in-place (:issue:`32831`)
363+
- Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`)
364+
363365

364366
Missing
365367
^^^^^^^

pandas/core/indexing.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -2045,9 +2045,9 @@ def __setitem__(self, key, value):
20452045

20462046
if not isinstance(key, tuple):
20472047
key = _tuplify(self.ndim, key)
2048+
key = list(self._convert_key(key, is_setter=True))
20482049
if len(key) != self.ndim:
20492050
raise ValueError("Not enough indexers for scalar access (setting)!")
2050-
key = list(self._convert_key(key, is_setter=True))
20512051
self.obj._set_value(*key, value=value, takeable=self._takeable)
20522052

20532053

@@ -2060,6 +2060,11 @@ def _convert_key(self, key, is_setter: bool = False):
20602060
Require they keys to be the same type as the index. (so we don't
20612061
fallback)
20622062
"""
2063+
# For series, unpacking key needs to result in the label.
2064+
# This is already the case for len(key) == 1; e.g. (1,)
2065+
if isinstance(self.obj, ABCSeries) and len(key) > 1:
2066+
key = (key,)
2067+
20632068
# allow arbitrary setting
20642069
if is_setter:
20652070
return list(key)

pandas/tests/indexing/test_scalar.py

+33
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,36 @@ def test_iat_series_with_period_index():
311311
expected = ser[index[0]]
312312
result = ser.iat[0]
313313
assert expected == result
314+
315+
316+
def test_tuple_indexed_series_at_get():
317+
# GH 26989
318+
# Series.at works with MultiIndex
319+
series = Series([1, 2], index=[(1, 2), (3, 4)])
320+
assert series.at[1, 2] == 1
321+
322+
323+
def test_tuple_indexed_series_at_set():
324+
# GH 26989
325+
# Series.at works with MultiIndex
326+
series = Series([1, 2], index=[(1, 2), (3, 4)])
327+
series.at[1, 2] = 3
328+
assert series.at[1, 2] == 3
329+
330+
331+
def test_multiindex_series_at_get():
332+
# GH 26989
333+
# Series.at works with MultiIndex
334+
series = Series([1, 2], index=[[1, 2], [3, 4]])
335+
assert series.at[1, 3] == 1
336+
assert series.loc[1, 3] == 1
337+
338+
339+
def test_multiindex_series_at_set():
340+
# GH 26989
341+
# Series.at works with MultiIndex
342+
series = Series([1, 2], index=[[1, 2], [3, 4]])
343+
series.at[1, 3] = 3
344+
assert series.at[1, 3] == 3
345+
series.loc[1, 3] = 4
346+
assert series.loc[1, 3] == 4

0 commit comments

Comments
 (0)