Skip to content

BUG: Improved error msg #32855

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

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
15f32b7
Bug: wrap scalar accessor in try/except block and generate a better e…
a-y-khan Mar 20, 2020
3ef72e6
Bug: test exceptions (GH9259).
a-y-khan Mar 20, 2020
5ce133a
Bug: document changes (GH9259).
a-y-khan Mar 20, 2020
5a3a43d
Bug: improve raises (GH9259).
a-y-khan Mar 20, 2020
e89c7d6
Bug: flake8 fix (GH9259).
a-y-khan Mar 20, 2020
1d4ad9c
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Mar 22, 2020
8ebadc7
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Mar 23, 2020
957f77e
Bug: incorporate PR feedback (GH9259).
a-y-khan Mar 23, 2020
b326574
Merge master, fix conflict.
a-y-khan Mar 28, 2020
c032efa
Merge master.
a-y-khan Mar 29, 2020
b1ee783
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Apr 5, 2020
451b6b6
Merge master.
a-y-khan Apr 7, 2020
f601fd3
Merge master, fix conflict.
a-y-khan Apr 12, 2020
2817147
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Apr 15, 2020
b275f21
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Apr 16, 2020
f924bf0
Merge upstream master and fix conflict.
a-y-khan Apr 17, 2020
88fadf8
Merge remote-tracking branch 'upstream/master' into improved_error_msg
a-y-khan Apr 17, 2020
90ac52b
Fix single letter variable based on PR feedback.
a-y-khan Apr 17, 2020
217a35a
Series from dataframe based on PR feedback.
a-y-khan Apr 17, 2020
f37ed23
Merge upstream master, fix conflict.
a-y-khan Apr 23, 2020
de6d168
Merge upstream master, fix conflict.
a-y-khan Apr 30, 2020
91961d6
Merge upstream master.
a-y-khan May 31, 2020
b792fea
Remove series from test.
a-y-khan Jun 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ Indexing
- Bug in :meth:`DataFrame.copy` _item_cache not invalidated after copy causes post-copy value updates to not be reflected (:issue:`31784`)
- Bug in `Series.__getitem__` with an integer key and a :class:`MultiIndex` with leading integer level failing to raise ``KeyError`` if the key is not present in the first level (:issue:`33355`)
- Bug in :meth:`DataFrame.iloc` when slicing a single column-:class:`DataFrame`` with ``ExtensionDtype`` (e.g. ``df.iloc[:, :1]``) returning an invalid result (:issue:`32957`)
- Calling :meth:`DataFrame.at` on a DataFrame with a MultiIndex raises an exception with a more informative message (:issue:`9259`)

Missing
^^^^^^^
Expand Down
11 changes: 10 additions & 1 deletion pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doing this on master, the DataFrame case is giving a reasonable message, while the Series case is unhelpful. Maybe condition this on self.ndim == 1 and add a suggestion "pass a tuple"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It the Series case goes down a different code path where an exception is raised in pandas/utils/_validators.py. Would adding an except for TypeError with a more informative error message work?

In [3]: ser.at["a_row", "A"]                                                                                  
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-2aec4c8078ba> in <module>
----> 1 ser.at["a_row", "A"]

/workspaces/pandas-aykhan/pandas/core/indexing.py in __getitem__(self, key)
   2090             return self.obj.loc[key]
   2091 
-> 2092         return super().__getitem__(key)
   2093 
   2094     def __setitem__(self, key, value):

/workspaces/pandas-aykhan/pandas/core/indexing.py in __getitem__(self, key)
   2035         try:
   2036             # import pdb; pdb.set_trace()
-> 2037             return self.obj._get_value(*key, takeable=self._takeable)
   2038         except KeyError as err:
   2039             if isinstance(self.obj.index, ABCMultiIndex):

TypeError: _get_value() got multiple values for argument 'takeable'

)
else:
raise

def __setitem__(self, key, value):
if isinstance(key, tuple):
Expand Down
18 changes: 18 additions & 0 deletions pandas/tests/indexes/multi/test_get_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,21 @@ 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),
)
s = pd.Series(np.linspace(1, 2, 2), index=pd.MultiIndex.from_tuples(idx))

with pytest.raises(KeyError, match=r".+? indexing with .+? failing for MultiIndex"):
df.at["a_row", "A"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a similar problem for at.__setitem__?

Copy link
Contributor Author

@a-y-khan a-y-khan Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiindex with at.__setitem__ doesn't raise an exception and sets items at level 0:

In [1]: import pandas as pd 
   ...: import numpy as np 
   ...:  
   ...: 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), 
   ...: ) 
   ...: display(df)
                                                                                                           
        a_col     
            A    B
a_row A   1.0  2.0
      B   3.0  4.0

In [2]: df.at["a_row", "A"] = 888.0 
   ...: display(df)
                                                                                                           
         a_col       
             A      B
a_row A  888.0  888.0
      B    3.0    4.0

In [3]: df.at["a_row", "A"] = [888.0, 999.0] 
   ...: display(df)
                                                                                                           
         a_col       
             A      B
a_row A  888.0  999.0
      B    3.0    4.0


with pytest.raises(TypeError, match=r".+? got multiple values for argument .+?"):
s.at["a_row", "A"]