Skip to content

Commit 083b1ec

Browse files
committed
[BUG] fix .at for multiindexed series
Addresses: GH26989
1 parent 4a267c6 commit 083b1ec

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

doc/source/whatsnew/v1.1.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ Indexing
717717
- Bug in :meth:`Series.__setitem__` with an :class:`IntervalIndex` and a list-like key of integers (:issue:`33473`)
718718
- Bug in :meth:`Series.__getitem__` allowing missing labels with ``np.ndarray``, :class:`Index`, :class:`Series` indexers but not ``list``, these now all raise ``KeyError`` (:issue:`33646`)
719719
- Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`)
720-
- Indexing with a list of strings representing datetimes failed on :class:`DatetimeIndex` or :class:`PeriodIndex`(:issue:`11278`)
720+
- Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`)
721721

722722
Missing
723723
^^^^^^^

pandas/core/indexing.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -2016,10 +2016,10 @@ def __setitem__(self, key, value):
20162016

20172017
if not isinstance(key, tuple):
20182018
key = _tuplify(self.ndim, key)
2019+
key = list(self._convert_key(key, is_setter=True))
20192020
if len(key) != self.ndim:
20202021
raise ValueError("Not enough indexers for scalar access (setting)!")
2021-
2022-
key = list(self._convert_key(key, is_setter=True))
2022+
20232023
self.obj._set_value(*key, value=value, takeable=self._takeable)
20242024

20252025

@@ -2032,6 +2032,11 @@ def _convert_key(self, key, is_setter: bool = False):
20322032
Require they keys to be the same type as the index. (so we don't
20332033
fallback)
20342034
"""
2035+
# For series, unpacking key needs to result in the label.
2036+
# This is already the case for len(key) == 1; e.g. (1,)
2037+
if isinstance(self.obj, ABCSeries) and len(key) > 1:
2038+
key = (key,)
2039+
20352040
# allow arbitrary setting
20362041
if is_setter:
20372042
return list(key)

pandas/tests/indexing/test_scalar.py

+33
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,36 @@ def test_iat_series_with_period_index():
351351
expected = ser[index[0]]
352352
result = ser.iat[0]
353353
assert expected == result
354+
355+
356+
def test_tuple_indexed_series_at_get():
357+
# GH 26989
358+
# Series.at works with MultiIndex
359+
series = Series([1, 2], index=[(1, 2), (3, 4)])
360+
assert series.at[1, 2] == 1
361+
362+
363+
def test_tuple_indexed_series_at_set():
364+
# GH 26989
365+
# Series.at works with MultiIndex
366+
series = Series([1, 2], index=[(1, 2), (3, 4)])
367+
series.at[1, 2] = 3
368+
assert series.at[1, 2] == 3
369+
370+
371+
def test_multiindex_series_at_get():
372+
# GH 26989
373+
# Series.at works with MultiIndex
374+
series = Series([1, 2], index=[[1, 2], [3, 4]])
375+
assert series.at[1, 3] == 1
376+
assert series.loc[1, 3] == 1
377+
378+
379+
def test_multiindex_series_at_set():
380+
# GH 26989
381+
# Series.at works with MultiIndex
382+
series = Series([1, 2], index=[[1, 2], [3, 4]])
383+
series.at[1, 3] = 3
384+
assert series.at[1, 3] == 3
385+
series.loc[1, 3] = 4
386+
assert series.loc[1, 3] == 4

0 commit comments

Comments
 (0)