-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
CLN: implement xs in terms of loc #6249
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
Comments
I don't think we should deprecate it. Why not just implement |
definitly should reimplement with above... deprecate because then the selection becomes less confusing, e.g. want to get a value by location, then use see #5421 |
Yeah, I just abhor having to type four lines instead of a call to |
no....that's the implementation....after #6134 you just do:
etc I suppose it has its uses instead of typing empty levels..(but that's about it) |
How will you disambiguate selecting a column by name with loc vs this kind of selection? Python makes no distinction between colon and none slices except at the syntactic level so your above example is equivalent to df.loc[:, key] which already does column selection. There's no way to tell apart what you've written above from that example. Am I missing something? |
hmm...this is a very good point..#6134 won't work as advertised then... easy way to 'fix' this is to allow a tuple/list for the how do we feel about
or to disambiguate
hmm.... |
@y-p want to weigh in here, I didn't think about this with #6134, how to disambiguate? e.g.
raises (even though we'd like it to work)
|
One tuple per axis.
as advertised in the #6134 example. |
doesn't work, its mis-interpreted because you cannot disambiguate |
Disambiguate with what? give me an example of something that's indistinguishable |
|
That's so broken. But, It also doesn't seem to be true:
am I missing something? |
with #6134
|
The difference is that you're passing in a tuple of tuples, so I was wrong about the equivalence. |
So you withdraw the claim that xs is still necessary, or are there other corner cases? |
There's no syntactic equivalent of nested tuples of slices, but I think allowing nested tuples as well as flat ones for indexing is going to be both confusing for users and a maintenance nightmare |
What are nested tuples? show me. |
tuples of tuples |
Where did I pass one in? |
Look at your example
first one is nested, second is not |
@y-p your example is tuple of tuples (not passed explicity, but generates it) |
@cpcloud actually I think this can work, but need to careful of figure out what is an axis part of the tuple |
I'm trying to find the python docs on this .... harder than i imagined |
I don't understand. |
@jreback I just think it's confusing for users (maybe it wouldn't be user facing?) and seems like a huge burden for anyone to maintain. It seems like missing parens are going to cause all sorts of confusino |
here's a decent ref |
I think is very natural actually; if you have multi-levels it is the only way to go e.g. imagine
|
This discussion is ridiculous and that objection is vapid. missing parens? what? |
@y-p I guess it does....nevermind then |
@y-p Sheesh. My mistake. Vapid is a bit much don't you think? Forget it. |
@y-p I think their is a bug in the interpreation of
should this not return
|
And by missing parens I meant |
I'm in a bad mood today, my apologies for snapping at you. Not ok. |
But as I said my objection was unwarranted. Carry on. |
do you agree that indexing with tuples has been around for a long time? |
@cpcloud the missing parens thing will be caught (maybe could have a better message though) |
@y-p Yes, they have. I guess I just never used them. Availability heuristic taking over it seems |
I really feel bad for getting carried away in the argument just then. I apologize again. In fact, several users have complained that they expect this syntax to work, Since the tuple indexing case already exists, I don't find the "maintenance" objection It's frustrating for me to have to fight such a barrage, but I've been even more |
@y-p Don't worry about it. You're right. Statement(s) rescinded. |
I'm going to step away from github for a few days, Clearly I'm starting to |
@cpcloud in #6301 I used the nested_tuple concept....which is what it actual is! I think we can just leave |
Cool. This is great. |
@jreback Forgive me if this is the wrong place to put this but I've been trying to implement This is what I currently have (inside of core/generic.py) def xs(self, key, axis=0, level=None, copy=None, drop_level=True):
axis = self._get_axis_number(axis)
axis_indexer = [ slice(None) ] * self.ndim
indexer = self._get_axis(axis)
if not isinstance(indexer,MultiIndex) or (level is None and drop_level):
# .loc works directly if the key is already ordered and you don't
# mind dropping levels (or if it's a regular index)
axis_indexer[axis] = key
return self.loc[tuple(axis_indexer)]
if level is None:
# fill in with slice(None)s to keep from dropping levels
slicer = [ slice(None) ] * indexer.nlevels
# Q: is it ok to always expect tuple for a multi-index key?
for i,k in enumerate(key if type(key) is tuple else (key,)):
slicer[i] = k
return self.loc[tuple(slicer)]
# let get_loc_level handle cases with both key and level
slicer, new_indexer = indexer.get_loc_level(key
,level=level
,drop_level=drop_level)
axis_indexer[axis] = slicer
result = self.loc[tuple(axis_indexer)]
# apply the new index to the result to drop levels as necessary
setattr(result,result._get_axis_name(axis), new_indexer)
# this could be a view
# but only in a single-dtyped view slicable case
result._set_is_copy(self, copy=not result._is_view)
return result Running the indexing tests, there are many failures but they all seem to be related to a loop that is created by calling $ nosetests pandas/tests/test_indexing.py:TestIndexing.test_iloc_getitem_multiindex
File /home/tdos/git/pandas/pandas/tests/test_indexing.py, line 1494, in test_iloc_getitem_multiindex
xp = mi_int.ix[4].ix[8]
File /home/tdos/git/pandas/pandas/core/indexing.py, line 70, in __getitem__
return self._getitem_axis(key, axis=0)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 920, in _getitem_axis
return self._get_label(key, axis=axis)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 86, in _get_label
return self.obj._xs(label, axis=axis)
File /home/tdos/git/pandas/pandas/core/generic.py, line 1455, in xs
return self.loc[tuple(axis_indexer)]
File /home/tdos/git/pandas/pandas/core/indexing.py, line 1187, in __getitem__
return self._getitem_tuple(key)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 700, in _getitem_tuple
return self._getitem_lowerdim(tup)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 808, in _getitem_lowerdim
return self._getitem_nested_tuple(tup)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 880, in _getitem_nested_tuple
obj = getattr(obj, self.name)._getitem_axis(key, axis=axis)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 1334, in _getitem_axis
return self._get_label(key, axis=axis)
File /home/tdos/git/pandas/pandas/core/indexing.py, line 86, in _get_label
return self.obj._xs(label, axis=axis)
File /home/tdos/git/pandas/pandas/core/generic.py, line 1455, in xs
return self.loc[tuple(axis_indexer)]
...
File "/home/tdos/git/pandas/pandas/core/indexing.py", line 1305, in _getitem_axis
elif is_bool_indexer(key):
File "/home/tdos/git/pandas/pandas/core/common.py", line 2126, in is_bool_indexer
if isinstance(key, (ABCSeries, np.ndarray)):
File "/home/tdos/git/pandas/pandas/core/common.py", line 72, in _check
return getattr(inst, attr, '_typ') in comp
RuntimeError: maximum recursion depth exceeded in cmp So it seems that the feedback loop follows the chain Any ideas on next steps? Or is there anything that sticks out in my code as possibly causing the problem? |
I think this should collapse to just a small amount of code, but i suppose you can iterate on that. can you point to your branch for this? |
so when you have an axis=0 indexer (and nothing else), you can collapse it and it will give you the result back, e.g.
is equiv to
|
@jreback yeah, I just wanted to get something that works and then simplify it. It seems though that I think that |
yeah prob a bit of recursion going on. Prob needs some simplifying |
Since |
after #6134 we can drop xs and implement directly. Thus we should deprecate it.
.xs(key, level=n)
is roughly equivalent to this
roughly because needs to handle
.xs
full argument setThe text was updated successfully, but these errors were encountered: