Skip to content
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

eval - 'Call' nodes are not implemented #4893

Closed
glaucouri opened this issue Sep 20, 2013 · 11 comments · Fixed by #10953
Closed

eval - 'Call' nodes are not implemented #4893

glaucouri opened this issue Sep 20, 2013 · 11 comments · Fixed by #10953
Labels
API Design Enhancement Numeric Operations Arithmetic, Comparison, and Logical operations
Milestone

Comments

@glaucouri
Copy link

df = P.DataFrame({'a':[1,1,2,2,3,3]})
df.eval("a.mean()")

raise:
NotImplementedError: 'Call' nodes are not implemented

i hope this will be possible
thank's
Gla

@cpcloud
Copy link
Member

cpcloud commented Sep 20, 2013

What you've got there doesn't make a whole lot of sense (maybe you're doing something that does and this is just an example):

df = DataFrame({'a': [1, 1, 2, 2, 3, 3]})
m = df.a.mean()
df.eval('m') == m
pd.eval('m') == m

so just evaluate it in Python.

No new features will be added to eval, query for the next release (0.13) and possibly even 0.14

@ghost ghost assigned cpcloud Sep 20, 2013
@cpcloud
Copy link
Member

cpcloud commented Sep 20, 2013

Slightly OT: @glaucouri Just in case that error message is a bit cryptic: A "Call" node is a node in the abstract syntax tree created by parsing Python source. Here is the language reference on callable objects.

@glaucouri
Copy link
Author

What i'm trying to explain (with my poor english) is that in an eval environment if [a] is a P.Series i expect that i can use a this syntax : ( this is my working program, that users can use for do personalized equations)

safe_env = dict( [(k,df[k]) for k in df.keys() ])
safe_env # some other injections from numpy
val = eval(equation,safe_env)
#now val is the result of the equation, so with a little of broadcasting i can insert it in the df

Actually, with this solution users can do filtering, grouping and equation in a DataFrame environment.

Thank's
Gla

@cpcloud
Copy link
Member

cpcloud commented Sep 20, 2013

@glaucouri What you've just described is essentially what happens under the hood in DataFrame.query()/DataFrame.eval(). Currently, you cannot call functions with either of those methods. Does that make sense?

@cpcloud
Copy link
Member

cpcloud commented Feb 23, 2014

Closing as stale ... not really a demand for this right now

@cpcloud cpcloud closed this as completed Feb 23, 2014
@xenoscopic
Copy link
Contributor

Out of curiosity, would a (well-written) pull request adding support for the numexpr intrinsic functions be accepted? I've noticed that there is a variable defined in the expression parser called _numexpr_supported_calls, which seems to enumerate these functions, but this variable doesn't seem to be used anywhere. Stuff like abs or some of the transcendental functions might be quite useful.

@jreback
Copy link
Contributor

jreback commented Jul 22, 2014

we always accept a well-written PR (even some not so well-written!) :)

@cpcloud
Copy link
Member

cpcloud commented Jul 22, 2014

@havoc-io Yes, a PR would be great! To get started (if you haven't already) take a look in pandas/computation/expr.py. This is where the parsing logic is implemented. You'd need to allow Call nodes by removing them from the set exclusion happening in the decorator.

Here's an example of what a Call node looks like for the code f(a, b, c=1):

import ast
from ast import *  # forgive the star import here
node = ast.parse('f(a, b, c=1)', mode='eval').body
node.func == Name(id='f', ctx=Load())
node.args == [Name(id='a', ctx=Load()), Name(id='b', ctx=Load())]
node.keywords == [keyword(arg='c', value=Num(n=1))]

You could probably skip implementing keyword arguments for now and just implement unary or binary functions to get a feel for how difficult (or not) it would be to do this.

@jreback jreback reopened this Jul 22, 2014
@jreback jreback modified the milestones: 0.15.1, Someday Jul 22, 2014
@xenoscopic
Copy link
Contributor

Eish, this may be a bit complicated actually, given the conditional handling of Call nodes (not to mention their subnodes). It might bloat the parsing code quite a bit, maybe more than it's worth. Perhaps simply transforming Series objects before evaling is going to be easier for now for my use case.

It may also not be as well-defined as I initially imagined. E.g., would you want the behavior for only the 'numexpr' engine or the 'python' engine as well (with appropriate replacement functions from math or NumPy)? I'm also not sure what the behavior should be if local_dict overrides one of the intrinsics - I'd have to see what numexpr does in this case.

Maybe best to leave this issue dead for now :(.

@cpcloud
Copy link
Member

cpcloud commented Jul 22, 2014

@havoc-io There are quite a few details to be worked out here, which is part of the reason I didn't implement these right away.

It would be nice to have the python engine for testing and speed comparisons, but you could also just test using regular numpy based, toplevel python code. Maybe see how hard it would be to do the simplest thing.

  • only numexpr for now
  • add the funcs to the global namespace (just for validation) ... this may require some kind of custom "delayed" call node that doesn't do anything because you don't want to actually evaluate it

@cpcloud
Copy link
Member

cpcloud commented Jul 22, 2014

I believe numexpr overrides intrinsics so a variable called sin wouldn't work.

@jreback jreback modified the milestones: 0.16.0, Next Major Release Mar 6, 2015
@jreback jreback modified the milestones: 0.17.0, Next Major Release Sep 2, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Design Enhancement Numeric Operations Arithmetic, Comparison, and Logical operations
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants