Skip to content

CLN: simplify comparison method, docstring cleanups #27923

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

Merged
merged 3 commits into from
Aug 15, 2019
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
4 changes: 2 additions & 2 deletions pandas/core/computation/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np

import pandas as pd
from pandas._config import get_option

# A token value Python's tokenizer probably will never use.
_BACKTICK_QUOTED_STRING = 100
Expand All @@ -11,7 +11,7 @@
def _ensure_decoded(s):
""" if we have bytes, decode them to unicode """
if isinstance(s, (np.bytes_, bytes)):
s = s.decode(pd.get_option("display.encoding"))
s = s.decode(get_option("display.encoding"))
return s


Expand Down
44 changes: 23 additions & 21 deletions pandas/core/computation/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,18 @@ def _bool_arith_check(


def evaluate(op, op_str, a, b, use_numexpr=True, **eval_kwargs):
""" evaluate and return the expression of the op on a and b

Parameters
----------

op : the actual operand
op_str: the string version of the op
a : left operand
b : right operand
use_numexpr : whether to try to use numexpr (default True)
"""
"""
Evaluate and return the expression of the op on a and b.

Parameters
----------
op : the actual operand
op_str : the string version of the op
a : left operand
b : right operand
use_numexpr : bool, default True
Whether to try to use numexpr.
"""

use_numexpr = use_numexpr and _bool_arith_check(op_str, a, b)
if use_numexpr:
Expand All @@ -222,16 +223,17 @@ def evaluate(op, op_str, a, b, use_numexpr=True, **eval_kwargs):


def where(cond, a, b, use_numexpr=True):
""" evaluate the where condition cond on a and b

Parameters
----------

cond : a boolean array
a : return if cond is True
b : return if cond is False
use_numexpr : whether to try to use numexpr (default True)
"""
"""
Evaluate the where condition cond on a and b

Parameters
----------
cond : ndarray[bool]
a : return if cond is True
b : return if cond is False
use_numexpr : bool, default True
Whether to try to use numexpr.
"""

if use_numexpr:
return _where(cond, a, b)
Expand Down
28 changes: 16 additions & 12 deletions pandas/core/computation/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@


class UndefinedVariableError(NameError):

"""NameError subclass for local variables."""
"""
NameError subclass for local variables.
"""

def __init__(self, name, is_local):
if is_local:
Expand Down Expand Up @@ -191,8 +192,8 @@ def __repr__(self):


class Op:

"""Hold an operator of arbitrary arity
"""
Hold an operator of arbitrary arity.
"""

def __init__(self, op, operands, *args, **kwargs):
Expand All @@ -204,8 +205,9 @@ def __iter__(self):
return iter(self.operands)

def __repr__(self):
"""Print a generic n-ary operator and its operands using infix
notation"""
"""
Print a generic n-ary operator and its operands using infix notation.
"""
# recurse over the operands
parened = ("({0})".format(pprint_thing(opr)) for opr in self.operands)
return pprint_thing(" {0} ".format(self.op).join(parened))
Expand Down Expand Up @@ -296,15 +298,15 @@ def _not_in(x, y):


def _cast_inplace(terms, acceptable_dtypes, dtype):
"""Cast an expression inplace.
"""
Cast an expression inplace.

Parameters
----------
terms : Op
The expression that should cast.
acceptable_dtypes : list of acceptable numpy.dtype
Will not cast if term's dtype in this list.

dtype : str or numpy.dtype
The dtype to cast to.
"""
Expand All @@ -325,8 +327,8 @@ def is_term(obj):


class BinOp(Op):

"""Hold a binary operator and its operands
"""
Hold a binary operator and its operands.

Parameters
----------
Expand Down Expand Up @@ -355,7 +357,8 @@ def __init__(self, op, lhs, rhs, **kwargs):
)

def __call__(self, env):
"""Recursively evaluate an expression in Python space.
"""
Recursively evaluate an expression in Python space.

Parameters
----------
Expand All @@ -377,7 +380,8 @@ def __call__(self, env):
return self.func(left, right)

def evaluate(self, env, engine, parser, term_type, eval_in_python):
"""Evaluate a binary operation *before* being passed to the engine.
"""
Evaluate a binary operation *before* being passed to the engine.

Parameters
----------
Expand Down
39 changes: 6 additions & 33 deletions pandas/core/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
is_period_dtype,
is_scalar,
is_timedelta64_dtype,
needs_i8_conversion,
)
from pandas.core.dtypes.generic import (
ABCDataFrame,
Expand Down Expand Up @@ -758,50 +757,24 @@ def _comp_method_SERIES(cls, op, special):
code duplication.
"""
op_name = _get_op_name(op, special)
masker = _gen_eval_kwargs(op_name).get("masker", False)

def na_op(x, y):
# TODO:
# should have guarantess on what x, y can be type-wise
# should have guarantees on what x, y can be type-wise
# Extension Dtypes are not called here

# Checking that cases that were once handled here are no longer
# reachable.
assert not (is_categorical_dtype(y) and not is_scalar(y))

if is_object_dtype(x.dtype):
result = _comp_method_OBJECT_ARRAY(op, x, y)

elif is_datetimelike_v_numeric(x, y):
return invalid_comparison(x, y, op)

else:

# we want to compare like types
# we only want to convert to integer like if
# we are not NotImplemented, otherwise
# we would allow datetime64 (but viewed as i8) against
# integer comparisons

# we have a datetime/timedelta and may need to convert
assert not needs_i8_conversion(x)
mask = None
if not is_scalar(y) and needs_i8_conversion(y):
mask = isna(x) | isna(y)
y = y.view("i8")
x = x.view("i8")

method = getattr(x, op_name, None)
if method is not None:
with np.errstate(all="ignore"):
result = method(y)
if result is NotImplemented:
return invalid_comparison(x, y, op)
else:
result = op(x, y)

if mask is not None and mask.any():
result[mask] = masker
method = getattr(x, op_name)
with np.errstate(all="ignore"):
result = method(y)
if result is NotImplemented:
return invalid_comparison(x, y, op)

return result

Expand Down