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

DOC: Fix inconsistent and incomplete documentation of pandas.eval #59855

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 28 additions & 9 deletions pandas/core/computation/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,6 @@ def eval(
"""
Evaluate a Python expression as a string using various backends.

The following arithmetic operations are supported: ``+``, ``-``, ``*``,
``/``, ``**``, ``%``, ``//`` (python engine only) along with the following
boolean operations: ``|`` (or), ``&`` (and), and ``~`` (not).
Additionally, the ``'pandas'`` parser allows the use of :keyword:`and`,
:keyword:`or`, and :keyword:`not` with the same semantics as the
corresponding bitwise operators. :class:`~pandas.Series` and
:class:`~pandas.DataFrame` objects are supported and behave as they would
with plain ol' Python evaluation.

.. warning::

``eval`` can run arbitrary code which can make you vulnerable to code
Expand All @@ -210,6 +201,34 @@ def eval(
<https://docs.python.org/3/reference/simple_stmts.html#simple-statements>`__,
only Python `expressions
<https://docs.python.org/3/reference/simple_stmts.html#expression-statements>`__.

By default, with the numexpr engine, the following operations are supported:

- Arthimetic operations: ``+``, ``-``, ``*``, ``/``, ``**``, ``%``
- Boolean operations: ``|`` (or), ``&`` (and), and ``~`` (not)
- Comparison operators: ``<``, ``<=``, ``==``, ``!=``, ``>=``, ``>``

Furthermore, the following mathematical functions are supported:

- Trigonometric: ``sin``, ``cos``, ``tan``, ``arcsin``, ``arccos``, \
``arctan``, ``arctan2``, ``sinh``, ``cosh``, ``tanh``, ``arcsinh``, \
``arccosh`` and ``arctanh``
- Logarithms: ``log`` natural, ``log10`` base 10, ``log1p`` log(1+x)
- Absolute Value ``abs``
- Square root ``sqrt``
- Exponential ``exp`` and Exponential minus one ``expm1``

See the numexpr engine `documentation
<https://numexpr.readthedocs.io/en/latest/user_guide.html#supported-functions>`__
for further function support details.

Using the ``'python'`` engine allows the use of native Python operators
such as floor division ``//``, in addition to built-in and user-defined
Python functions.

Additionally, the ``'pandas'`` parser allows the use of :keyword:`and`,
:keyword:`or`, and :keyword:`not` with the same semantics as the
corresponding bitwise operators.
parser : {'pandas', 'python'}, default 'pandas'
The parser to use to construct the syntax tree from the expression. The
default of ``'pandas'`` parses code slightly different than standard
Expand Down
33 changes: 17 additions & 16 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -4479,20 +4479,11 @@ def query(self, expr: str, *, inplace: bool = False, **kwargs) -> DataFrame | No
expr : str
The query string to evaluate.

You can refer to variables
in the environment by prefixing them with an '@' character like
``@a + b``.

You can refer to column names that are not valid Python variable names
by surrounding them in backticks. Thus, column names containing spaces
or punctuation (besides underscores) or starting with digits must be
surrounded by backticks. (For example, a column named "Area (cm^2)" would
be referenced as ```Area (cm^2)```). Column names which are Python keywords
(like "if", "for", "import", etc) cannot be used.

For example, if one of your columns is called ``a a`` and you want
to sum it with ``b``, your query should be ```a a` + b``.
See the documentation for :func:`eval` for details of
supported operations and functions in the query string.

See the documentation for :meth:`DataFrame.eval` for details on
referring to column names and variables in the query string.
inplace : bool
Whether to modify the DataFrame rather than creating a new one.
**kwargs
Expand Down Expand Up @@ -4651,16 +4642,26 @@ def eval(self, expr: str, *, inplace: bool = False, **kwargs) -> Any | None:
in the environment by prefixing them with an '@' character like
``@a + b``.

You can refer to column names that are not valid Python variable
names by surrounding them with backticks `````.
You can refer to column names that are not valid Python variable names
by surrounding them in backticks. Thus, column names containing spaces
or punctuation (besides underscores) or starting with digits must be
surrounded by backticks. (For example, a column named "Area (cm^2)" would
be referenced as ```Area (cm^2)```). Column names which are Python keywords
(like "if", "for", "import", etc) cannot be used.

For example, if one of your columns is called ``a a`` and you want
to sum it with ``b``, your query should be ```a a` + b``.

See the documentation for :func:`eval` for full details of
supported operations and functions in the expression string.
inplace : bool, default False
If the expression contains an assignment, whether to perform the
operation inplace and mutate the existing DataFrame. Otherwise,
a new DataFrame is returned.
**kwargs
See the documentation for :func:`eval` for complete details
on the keyword arguments accepted by
:meth:`~pandas.DataFrame.query`.
:meth:`~pandas.DataFrame.eval`.

Returns
-------
Expand Down