diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 88bf0e005a221..23ec28d6f5818 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -843,6 +843,7 @@ Indexing - Bug in :meth:`DataFrame.truncate` and :meth:`Series.truncate` where index was assumed to be monotone increasing (:issue:`33756`) - Indexing with a list of strings representing datetimes failed on :class:`DatetimeIndex` or :class:`PeriodIndex`(:issue:`11278`) - Bug in :meth:`Series.at` when used with a :class:`MultiIndex` would raise an exception on valid inputs (:issue:`26989`) +- Calling :meth:`DataFrame.at` on a DataFrame with a MultiIndex raises an exception with a more informative message (:issue:`9259`) Missing ^^^^^^^ diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 3a146bb0438c5..e5871e7e00807 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2005,7 +2005,16 @@ def __getitem__(self, key): raise ValueError("Invalid call for scalar access (getting)!") key = self._convert_key(key) - return self.obj._get_value(*key, takeable=self._takeable) + try: + return self.obj._get_value(*key, takeable=self._takeable) + except KeyError as err: + if isinstance(self.obj.index, ABCMultiIndex): + raise KeyError( + f"Detected KeyError {err}, indexing with {key} " + "failing for MultiIndex" + ) + else: + raise def __setitem__(self, key, value): if isinstance(key, tuple): diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py index 8a3deca0236e4..9ca3fbc615e8d 100644 --- a/pandas/tests/indexes/multi/test_get_set.py +++ b/pandas/tests/indexes/multi/test_get_set.py @@ -329,3 +329,17 @@ def test_set_levels_with_iterable(): [expected_sizes, colors], names=["size", "color"] ) tm.assert_index_equal(result, expected) + + +def test_at_indexing_fails_multiindex(): + # GH9259 + cols = [("a_col", chr(i + 65)) for i in range(2)] + idx = [("a_row", chr(i + 65)) for i in range(2)] + df = pd.DataFrame( + np.linspace(1, 4, 4).reshape(2, 2), + index=pd.MultiIndex.from_tuples(idx), + columns=pd.MultiIndex.from_tuples(cols), + ) + + with pytest.raises(KeyError, match=r".+? indexing with .+? failing for MultiIndex"): + df.at["a_row", "A"]